InputMethodService.java revision c0c8765719f5c8d0192aa266c27166bdd8c09a33
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 android.inputmethodservice;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guyimport static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.Dialog;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Configuration;
25d922ae01ca99a2b6d39a9393f86776a1d10ebd14Dianne Hackbornimport android.content.res.Resources;
26105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport android.content.res.TypedArray;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect;
28fbf097732137a32930d151f7ba6816a5b870c32aJeff Brownimport android.graphics.Region;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder;
314df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Projectimport android.os.ResultReceiver;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.InputType;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Layout;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.Spannable;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.method.MovementMethod;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.PrintWriterPrinter;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Printer;
416b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brownimport android.view.KeyCharacterMap;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.LayoutInflater;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.MotionEvent;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewGroup;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.ViewTreeObserver;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.Window;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowManager;
50105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport android.view.animation.AnimationUtils;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.CompletionInfo;
528cbb4c6e30cff706a243599634aeb8fd9a818d92Gilles Debunneimport android.view.inputmethod.EditorInfo;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.ExtractedText;
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.ExtractedTextRequest;
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputBinding;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputConnection;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethod;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethodManager;
59ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokimport android.view.inputmethod.InputMethodSubtype;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.Button;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.widget.FrameLayout;
62105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport android.widget.LinearLayout;
63105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * InputMethodService provides a standard implementation of an InputMethod,
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * which final implementations can derive from and customize.  See the
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * base class {@link AbstractInputMethodService} and the {@link InputMethod}
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * interface for more information on the basics of writing input methods.
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>In addition to the normal Service lifecycle methods, this class
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * introduces some new specific callbacks that most subclasses will want
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to make use of:</p>
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul>
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> {@link #onInitializeInterface()} for user-interface initialization,
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in particular to deal with configuration changes while the service is
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * running.
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> {@link #onBindInput} to find out about switching to a new client.
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> {@link #onStartInput} to deal with an input session starting with
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the client.
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> {@link #onCreateInputView()}, {@link #onCreateCandidatesView()},
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and {@link #onCreateExtractTextView()} for non-demand generation of the UI.
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> {@link #onStartInputView(EditorInfo, boolean)} to deal with input
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * starting within the input area of the IME.
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul>
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>An input method has significant discretion in how it goes about its
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * work: the {@link android.inputmethodservice.InputMethodService} provides
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a basic framework for standard UI elements (input view, candidates view,
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and running in fullscreen mode), but it is up to a particular implementor
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to decide how to use them.  For example, one input method could implement
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * an input area with a keyboard, another could allow the user to draw text,
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * while a third could have no input area (and thus not be visible to the
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * user) but instead listen to audio and perform text to speech conversion.</p>
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>In the implementation provided here, all of these elements are placed
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * together in a single window managed by the InputMethodService.  It will
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * execute callbacks as it needs information about them, and provides APIs for
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * programmatic control over them.  They layout of these elements is explicitly
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * defined:</p>
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul>
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>The soft input view, if available, is placed at the bottom of the
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * screen.
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>The candidates view, if currently shown, is placed above the soft
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * input view.
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li>If not running fullscreen, the application is moved or resized to be
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * above these views; if running fullscreen, the window will completely cover
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the application and its top part will contain the extract text of what is
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * currently being edited by the application.
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul>
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <a name="SoftInputView"></a>
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h3>Soft Input View</h3>
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Central to most input methods is the soft input view.  This is where most
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * user interaction occurs: pressing on soft keys, drawing characters, or
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * however else your input method wants to generate text.  Most implementations
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will simply have their own view doing all of this work, and return a new
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instance of it when {@link #onCreateInputView()} is called.  At that point,
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as long as the input view is visible, you will see user interaction in
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that view and can call back on the InputMethodService to interact with the
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * application as appropriate.</p>
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>There are some situations where you want to decide whether or not your
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * soft input view should be shown to the user.  This is done by implementing
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the {@link #onEvaluateInputViewShown()} to return true or false based on
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * whether it should be shown in the current environment.  If any of your
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * state has changed that may impact this, call
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #updateInputViewShown()} to have it re-evaluated.  The default
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * implementation always shows the input view unless there is a hard
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * keyboard available, which is the appropriate behavior for most input
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * methods.</p>
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <a name="CandidatesView"></a>
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h3>Candidates View</h3>
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Often while the user is generating raw text, an input method wants to
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * provide them with a list of possible interpretations of that text that can
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be selected for use.  This is accomplished with the candidates view, and
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * like the soft input view you implement {@link #onCreateCandidatesView()}
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to instantiate your own view implementing your candidates UI.</p>
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Management of the candidates view is a little different than the input
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * view, because the candidates view tends to be more transient, being shown
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * only when there are possible candidates for the current text being entered
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the user.  To control whether the candidates view is shown, you use
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #setCandidatesViewShown(boolean)}.  Note that because the candidate
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * view tends to be shown and hidden a lot, it does not impact the application
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * UI in the same way as the soft input view: it will never cause application
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * windows to resize, only cause them to be panned if needed for the user to
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * see the current focus.</p>
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <a name="FullscreenMode"></a>
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h3>Fullscreen Mode</h3>
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Sometimes your input method UI is too large to integrate with the
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * application UI, so you just want to take over the screen.  This is
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * accomplished by switching to full-screen mode, causing the input method
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * window to fill the entire screen and add its own "extracted text" editor
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * showing the user the text that is being typed.  Unlike the other UI elements,
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * there is a standard implementation for the extract editor that you should
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * not need to change.  The editor is placed at the top of the IME, above the
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * input and candidates views.</p>
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Similar to the input view, you control whether the IME is running in
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * fullscreen mode by implementing {@link #onEvaluateFullscreenMode()}
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to return true or false based on
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * whether it should be fullscreen in the current environment.  If any of your
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * state has changed that may impact this, call
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #updateFullscreenMode()} to have it re-evaluated.  The default
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * implementation selects fullscreen mode when the screen is in a landscape
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * orientation, which is appropriate behavior for most input methods that have
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a significant input area.</p>
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>When in fullscreen mode, you have some special requirements because the
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * user can not see the application UI.  In particular, you should implement
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #onDisplayCompletions(CompletionInfo[])} to show completions
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * generated by your application, typically in your candidates view like you
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * would normally show candidates.
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <a name="GeneratingText"></a>
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h3>Generating Text</h3>
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The key part of an IME is of course generating text for the application.
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is done through calls to the
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.view.inputmethod.InputConnection} interface to the
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * application, which can be retrieved from {@link #getCurrentInputConnection()}.
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This interface allows you to generate raw key events or, if the target
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * supports it, directly edit in strings of candidates and committed text.</p>
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Information about what the target is expected and supports can be found
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * through the {@link android.view.inputmethod.EditorInfo} class, which is
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * retrieved with {@link #getCurrentInputEditorInfo()} method.  The most
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * important part of this is {@link android.view.inputmethod.EditorInfo#inputType
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * EditorInfo.inputType}; in particular, if this is
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.view.inputmethod.EditorInfo#TYPE_NULL EditorInfo.TYPE_NULL},
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * then the target does not support complex edits and you need to only deliver
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * raw key events to it.  An input method will also want to look at other
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * values here, to for example detect password mode, auto complete text views,
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * phone number entry, etc.</p>
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>When the user switches between input targets, you will receive calls to
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #onFinishInput()} and {@link #onStartInput(EditorInfo, boolean)}.
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You can use these to reset and initialize your input state for the current
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * target.  For example, you will often want to clear any input state, and
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * update a soft keyboard to be appropriate for the new inputType.</p>
214105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project *
215105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project * @attr ref android.R.styleable#InputMethodService_imeFullscreenBackground
216105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project * @attr ref android.R.styleable#InputMethodService_imeExtractEnterAnimation
217105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project * @attr ref android.R.styleable#InputMethodService_imeExtractExitAnimation
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class InputMethodService extends AbstractInputMethodService {
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String TAG = "InputMethodService";
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final boolean DEBUG = false;
222857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato
223857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    /**
224857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato     * The back button will close the input window.
225857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato     */
226857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    public static final int BACK_DISPOSITION_DEFAULT = 0;  // based on window
227857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato
228857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    /**
229857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato     * This input method will not consume the back key.
230857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato     */
231857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    public static final int BACK_DISPOSITION_WILL_NOT_DISMISS = 1; // back
232857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato
233857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    /**
234857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato     * This input method will consume the back key.
235857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato     */
236857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    public static final int BACK_DISPOSITION_WILL_DISMISS = 2; // down
237857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato
238857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    /**
239857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato     * @hide
240857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato     * The IME is active.  It may or may not be visible.
241857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato     */
242857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    public static final int IME_ACTIVE = 0x1;
243857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato
244857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    /**
245857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato     * @hide
246857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato     * The IME is visible.
247857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato     */
248857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    public static final int IME_VISIBLE = 0x2;
249857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    InputMethodManager mImm;
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
252d922ae01ca99a2b6d39a9393f86776a1d10ebd14Dianne Hackborn    int mTheme = 0;
253105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    LayoutInflater mInflater;
255105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    TypedArray mThemeAttrs;
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    View mRootView;
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SoftInputWindow mWindow;
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mInitialized;
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mWindowCreated;
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mWindowAdded;
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mWindowVisible;
262105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    boolean mWindowWasVisible;
263105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    boolean mInShowWindow;
264105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    ViewGroup mFullscreenArea;
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FrameLayout mExtractFrame;
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FrameLayout mCandidatesFrame;
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    FrameLayout mInputFrame;
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IBinder mToken;
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    InputBinding mInputBinding;
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    InputConnection mInputConnection;
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mInputStarted;
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mInputViewStarted;
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mCandidatesViewStarted;
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    InputConnection mStartedInputConnection;
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    EditorInfo mInputEditorInfo;
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mShowInputFlags;
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mShowInputRequested;
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mLastShowInputRequested;
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mCandidatesVisibility;
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CompletionInfo[] mCurCompletions;
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mShowInputForced;
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mFullscreenApplied;
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mIsFullscreen;
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    View mExtractView;
290105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    boolean mExtractViewHidden;
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ExtractEditText mExtractEditText;
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ViewGroup mExtractAccessories;
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Button mExtractAction;
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ExtractedText mExtractedText;
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mExtractedToken;
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    View mInputView;
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mIsInputViewShown;
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mStatusIcon;
301857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    int mBackDisposition;
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final Insets mTmpInsets = new Insets();
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final int[] mTmpLocation = new int[2];
305ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsComputer =
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            new ViewTreeObserver.OnComputeInternalInsetsListener() {
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
309105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            if (isExtractViewShown()) {
310105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                // In true fullscreen mode, we just say the window isn't covering
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // any content so we don't impact whatever is behind.
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                View decor = getWindow().getWindow().getDecorView();
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                info.contentInsets.top = info.visibleInsets.top
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        = decor.getHeight();
315fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown                info.touchableRegion.setEmpty();
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                onComputeInsets(mTmpInsets);
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                info.contentInsets.top = mTmpInsets.contentTopInsets;
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                info.visibleInsets.top = mTmpInsets.visibleTopInsets;
321fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown                info.touchableRegion.set(mTmpInsets.touchableRegion);
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                info.setTouchableInsets(mTmpInsets.touchableInsets);
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final View.OnClickListener mActionClickListener = new View.OnClickListener() {
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onClick(View v) {
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final EditorInfo ei = getCurrentInputEditorInfo();
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final InputConnection ic = getCurrentInputConnection();
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ei != null && ic != null) {
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (ei.actionId != 0) {
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ic.performEditorAction(ei.actionId);
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if ((ei.imeOptions&EditorInfo.IME_MASK_ACTION)
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        != EditorInfo.IME_ACTION_NONE) {
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ic.performEditorAction(ei.imeOptions&EditorInfo.IME_MASK_ACTION);
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Concrete implementation of
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link AbstractInputMethodService.AbstractInputMethodImpl} that provides
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * all of the standard behavior for an input method.
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public class InputMethodImpl extends AbstractInputMethodImpl {
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Take care of attaching the given window token provided by the system.
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void attachToken(IBinder token) {
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mToken == null) {
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mToken = token;
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mWindow.setToken(token);
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Handle a new input binding, calling
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * {@link InputMethodService#onBindInput InputMethodService.onBindInput()}
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * when done.
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void bindInput(InputBinding binding) {
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInputBinding = binding;
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInputConnection = binding.getConnection();
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "bindInput(): binding=" + binding
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " ic=" + mInputConnection);
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputConnection ic = getCurrentInputConnection();
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ic != null) ic.reportFullscreenMode(mIsFullscreen);
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            initialize();
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onBindInput();
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Clear the current input binding.
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void unbindInput() {
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "unbindInput(): binding=" + mInputBinding
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " ic=" + mInputConnection);
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onUnbindInput();
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInputStarted = false;
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInputBinding = null;
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInputConnection = null;
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void startInput(InputConnection ic, EditorInfo attribute) {
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "startInput(): editor=" + attribute);
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doStartInput(ic, attribute, false);
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void restartInput(InputConnection ic, EditorInfo attribute) {
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "restartInput(): editor=" + attribute);
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doStartInput(ic, attribute, true);
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Handle a request by the system to hide the soft input area.
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
3994df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        public void hideSoftInput(int flags, ResultReceiver resultReceiver) {
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "hideSoftInput()");
4014df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            boolean wasVis = isInputViewShown();
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mShowInputFlags = 0;
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mShowInputRequested = false;
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mShowInputForced = false;
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hideWindow();
4064df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            if (resultReceiver != null) {
4074df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                resultReceiver.send(wasVis != isInputViewShown()
4084df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                        ? InputMethodManager.RESULT_HIDDEN
4094df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                        : (wasVis ? InputMethodManager.RESULT_UNCHANGED_SHOWN
4104df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                                : InputMethodManager.RESULT_UNCHANGED_HIDDEN), null);
4114df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            }
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Handle a request by the system to show the soft input area.
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
4174df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        public void showSoftInput(int flags, ResultReceiver resultReceiver) {
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "showSoftInput()");
4194df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            boolean wasVis = isInputViewShown();
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mShowInputFlags = 0;
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (onShowInputRequested(flags, false)) {
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                showWindow(true);
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
424865b97761cc58053f45a8b06b531d60d8e482c3asatok            // If user uses hard keyboard, IME button should always be shown.
425857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato            boolean showing = onEvaluateInputViewShown();
426857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato            mImm.setImeWindowStatus(mToken, IME_ACTIVE | (showing ? IME_VISIBLE : 0),
427857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato                    mBackDisposition);
4284df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            if (resultReceiver != null) {
4294df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                resultReceiver.send(wasVis != isInputViewShown()
4304df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                        ? InputMethodManager.RESULT_SHOWN
4314df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                        : (wasVis ? InputMethodManager.RESULT_UNCHANGED_SHOWN
4324df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                                : InputMethodManager.RESULT_UNCHANGED_HIDDEN), null);
4334df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            }
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
435ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok
436ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok        public void changeInputMethodSubtype(InputMethodSubtype subtype) {
437ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok            onCurrentInputMethodSubtypeChanged(subtype);
438ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok        }
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
440ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Concrete implementation of
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link AbstractInputMethodService.AbstractInputMethodSessionImpl} that provides
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * all of the standard behavior for an input method session.
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public class InputMethodSessionImpl extends AbstractInputMethodSessionImpl {
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void finishInput() {
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!isEnabled()) {
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "finishInput() in " + this);
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doFinishInput();
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Call {@link InputMethodService#onDisplayCompletions
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * InputMethodService.onDisplayCompletions()}.
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void displayCompletions(CompletionInfo[] completions) {
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!isEnabled()) {
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurCompletions = completions;
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onDisplayCompletions(completions);
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Call {@link InputMethodService#onUpdateExtractedText
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * InputMethodService.onUpdateExtractedText()}.
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void updateExtractedText(int token, ExtractedText text) {
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!isEnabled()) {
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onUpdateExtractedText(token, text);
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Call {@link InputMethodService#onUpdateSelection
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * InputMethodService.onUpdateSelection()}.
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void updateSelection(int oldSelStart, int oldSelEnd,
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int newSelStart, int newSelEnd,
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int candidatesStart, int candidatesEnd) {
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!isEnabled()) {
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputMethodService.this.onUpdateSelection(oldSelStart, oldSelEnd,
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    newSelStart, newSelEnd, candidatesStart, candidatesEnd);
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
491863fcd62171e55bc9f2105d9fb5877df982454d8satok
492863fcd62171e55bc9f2105d9fb5877df982454d8satok        @Override
493863fcd62171e55bc9f2105d9fb5877df982454d8satok        public void viewClicked(boolean focusChanged) {
494863fcd62171e55bc9f2105d9fb5877df982454d8satok            if (!isEnabled()) {
495863fcd62171e55bc9f2105d9fb5877df982454d8satok                return;
496863fcd62171e55bc9f2105d9fb5877df982454d8satok            }
497863fcd62171e55bc9f2105d9fb5877df982454d8satok            InputMethodService.this.onViewClicked(focusChanged);
498863fcd62171e55bc9f2105d9fb5877df982454d8satok        }
499863fcd62171e55bc9f2105d9fb5877df982454d8satok
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Call {@link InputMethodService#onUpdateCursor
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * InputMethodService.onUpdateCursor()}.
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void updateCursor(Rect newCursor) {
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!isEnabled()) {
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputMethodService.this.onUpdateCursor(newCursor);
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Call {@link InputMethodService#onAppPrivateCommand
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * InputMethodService.onAppPrivateCommand()}.
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void appPrivateCommand(String action, Bundle data) {
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!isEnabled()) {
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputMethodService.this.onAppPrivateCommand(action, data);
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5214df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project
5224df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        /**
5234df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project         *
5244df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project         */
5254df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        public void toggleSoftInput(int showFlags, int hideFlags) {
5264df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            InputMethodService.this.onToggleSoftInput(showFlags, hideFlags);
5274df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        }
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Information about where interesting parts of the input method UI appear.
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static final class Insets {
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * This is the top part of the UI that is the main content.  It is
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * used to determine the basic space needed, to resize/pan the
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * application behind.  It is assumed that this inset does not
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * change very much, since any change will cause a full resize/pan
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * of the application behind.  This value is relative to the top edge
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * of the input method window.
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int contentTopInsets;
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * This is the top part of the UI that is visibly covering the
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * application behind it.  This provides finer-grained control over
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * visibility, allowing you to change it relatively frequently (such
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * as hiding or showing candidates) without disrupting the underlying
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * UI too much.  For example, this will never resize the application
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * UI, will only pan if needed to make the current focus visible, and
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * will not aggressively move the pan position when this changes unless
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * needed to make the focus visible.  This value is relative to the top edge
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * of the input method window.
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int visibleTopInsets;
556fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown
557fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown        /**
558fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown         * This is the region of the UI that is touchable.  It is used when
559fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown         * {@link #touchableInsets} is set to {@link #TOUCHABLE_INSETS_REGION}.
560fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown         * The region should be specified relative to the origin of the window frame.
561fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown         */
562fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown        public final Region touchableRegion = new Region();
563fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Option for {@link #touchableInsets}: the entire window frame
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * can be touched.
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public static final int TOUCHABLE_INSETS_FRAME
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Option for {@link #touchableInsets}: the area inside of
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the content insets can be touched.
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public static final int TOUCHABLE_INSETS_CONTENT
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Option for {@link #touchableInsets}: the area inside of
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * the visible insets can be touched.
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public static final int TOUCHABLE_INSETS_VISIBLE
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE;
584fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown
585fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown        /**
586fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown         * Option for {@link #touchableInsets}: the region specified by
587fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown         * {@link #touchableRegion} can be touched.
588fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown         */
589fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown        public static final int TOUCHABLE_INSETS_REGION
590fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown                = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
591fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * Determine which area of the window is touchable by the user.  May
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * be one of: {@link #TOUCHABLE_INSETS_FRAME},
595fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown         * {@link #TOUCHABLE_INSETS_CONTENT}, {@link #TOUCHABLE_INSETS_VISIBLE},
596fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown         * or {@link #TOUCHABLE_INSETS_REGION}.
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public int touchableInsets;
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
600865b97761cc58053f45a8b06b531d60d8e482c3asatok
601105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    /**
602105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * You can call this to customize the theme used by your IME's window.
603105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * This theme should typically be one that derives from
604105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * {@link android.R.style#Theme_InputMethod}, which is the default theme
605105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * you will get.  This must be set before {@link #onCreate}, so you
606105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * will typically call it in your constructor with the resource ID
607105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * of your custom theme.
608105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     */
609ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    @Override
610105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    public void setTheme(int theme) {
611105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (mWindow != null) {
612105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            throw new IllegalStateException("Must be called before onCreate()");
613105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
614105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        mTheme = theme;
615105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
616865b97761cc58053f45a8b06b531d60d8e482c3asatok
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override public void onCreate() {
618d922ae01ca99a2b6d39a9393f86776a1d10ebd14Dianne Hackborn        mTheme = Resources.selectSystemTheme(mTheme,
619d922ae01ca99a2b6d39a9393f86776a1d10ebd14Dianne Hackborn                getApplicationInfo().targetSdkVersion,
6206e90a362bc66cc67b1beae27b21d3f0148403b08Adam Powell                android.R.style.Theme_InputMethod,
62136a97e4030010298736928f9b391a390fea6941bAdam Powell                android.R.style.Theme_Holo_InputMethod,
6226e90a362bc66cc67b1beae27b21d3f0148403b08Adam Powell                android.R.style.Theme_DeviceDefault_InputMethod);
623105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        super.setTheme(mTheme);
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onCreate();
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mImm = (InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInflater = (LayoutInflater)getSystemService(
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Context.LAYOUT_INFLATER_SERVICE);
62883fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        mWindow = new SoftInputWindow(this, mTheme, mDispatcherState);
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        initViews();
630980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy        mWindow.getWindow().setLayout(MATCH_PARENT, WRAP_CONTENT);
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
632ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is a hook that subclasses can use to perform initialization of
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * their interface.  It is called for you prior to any of your UI objects
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * being created, both after the service is first created and after a
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * configuration change happens.
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onInitializeInterface() {
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
641ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void initialize() {
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mInitialized) {
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInitialized = true;
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onInitializeInterface();
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
648ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void initViews() {
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInitialized = false;
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWindowCreated = false;
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mShowInputRequested = false;
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mShowInputForced = false;
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
655105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        mThemeAttrs = obtainStyledAttributes(android.R.styleable.InputMethodService);
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRootView = mInflater.inflate(
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                com.android.internal.R.layout.input_method, null);
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWindow.setContentView(mRootView);
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRootView.getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsComputer);
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (Settings.System.getInt(getContentResolver(),
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Settings.System.FANCY_IME_ANIMATIONS, 0) != 0) {
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWindow.getWindow().setWindowAnimations(
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    com.android.internal.R.style.Animation_InputMethodFancy);
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
665105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        mFullscreenArea = (ViewGroup)mRootView.findViewById(com.android.internal.R.id.fullscreenArea);
666105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        mExtractViewHidden = false;
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mExtractFrame = (FrameLayout)mRootView.findViewById(android.R.id.extractArea);
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mExtractView = null;
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mExtractEditText = null;
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mExtractAccessories = null;
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mExtractAction = null;
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mFullscreenApplied = false;
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCandidatesFrame = (FrameLayout)mRootView.findViewById(android.R.id.candidatesArea);
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputFrame = (FrameLayout)mRootView.findViewById(android.R.id.inputArea);
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputView = null;
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIsInputViewShown = false;
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mExtractFrame.setVisibility(View.GONE);
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCandidatesVisibility = getCandidatesHiddenVisibility();
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCandidatesFrame.setVisibility(mCandidatesVisibility);
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputFrame.setVisibility(View.GONE);
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
684ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override public void onDestroy() {
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onDestroy();
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRootView.getViewTreeObserver().removeOnComputeInternalInsetsListener(
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mInsetsComputer);
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mWindowAdded) {
690c0c8765719f5c8d0192aa266c27166bdd8c09a33satok            // Disable exit animation for the current IME window
691c0c8765719f5c8d0192aa266c27166bdd8c09a33satok            // to avoid the race condition between the exit and enter animations
692c0c8765719f5c8d0192aa266c27166bdd8c09a33satok            // when the current IME is being switched to another one.
693c0c8765719f5c8d0192aa266c27166bdd8c09a33satok            mWindow.getWindow().setWindowAnimations(0);
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWindow.dismiss();
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Take care of handling configuration changes.  Subclasses of
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * InputMethodService generally don't need to deal directly with
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this on their own; the standard implementation here takes care of
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * regenerating the input method UI as a result of the configuration
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * change, so you can rely on your {@link #onCreateInputView} and
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * other methods being called as appropriate due to a configuration change.
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>When a configuration change does happen,
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #onInitializeInterface()} is guaranteed to be called the next
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * time prior to any of the other input or UI creation callbacks.  The
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * following will be called immediately depending if appropriate for current
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * state: {@link #onStartInput} if input is active, and
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #onCreateInputView} and {@link #onStartInputView} and related
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * appropriate functions if the UI is displayed.
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override public void onConfigurationChanged(Configuration newConfig) {
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onConfigurationChanged(newConfig);
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean visible = mWindowVisible;
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int showFlags = mShowInputFlags;
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean showingInput = mShowInputRequested;
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CompletionInfo[] completions = mCurCompletions;
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        initViews();
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputViewStarted = false;
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCandidatesViewStarted = false;
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mInputStarted) {
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doStartInput(getCurrentInputConnection(),
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    getCurrentInputEditorInfo(), true);
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (visible) {
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (showingInput) {
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // If we were last showing the soft keyboard, try to do so again.
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (onShowInputRequested(showFlags, true)) {
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    showWindow(true);
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (completions != null) {
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mCurCompletions = completions;
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        onDisplayCompletions(completions);
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hideWindow();
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (mCandidatesVisibility == View.VISIBLE) {
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // If the candidates are currently visible, make sure the
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // window is shown for them.
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                showWindow(false);
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Otherwise hide the window.
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hideWindow();
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
748865b97761cc58053f45a8b06b531d60d8e482c3asatok            // If user uses hard keyboard, IME button should always be shown.
749857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato            boolean showing = onEvaluateInputViewShown();
750857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato            mImm.setImeWindowStatus(mToken, IME_ACTIVE | (showing ? IME_VISIBLE : 0),
751857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato                    mBackDisposition);
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Implement to return our standard {@link InputMethodImpl}.  Subclasses
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can override to provide their own customized version.
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
759ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    @Override
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AbstractInputMethodImpl onCreateInputMethodInterface() {
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new InputMethodImpl();
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Implement to return our standard {@link InputMethodSessionImpl}.  Subclasses
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can override to provide their own customized version.
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
768ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    @Override
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface() {
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new InputMethodSessionImpl();
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public LayoutInflater getLayoutInflater() {
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInflater;
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Dialog getWindow() {
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mWindow;
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
781857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    public void setBackDisposition(int disposition) {
782857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato        mBackDisposition = disposition;
783857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    }
784857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato
785857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    public int getBackDisposition() {
786857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato        return mBackDisposition;
787857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    }
788857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the maximum width, in pixels, available the input method.
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Input methods are positioned at the bottom of the screen and, unless
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * running in fullscreen, will generally want to be as short as possible
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * so should compute their height based on their contents.  However, they
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can stretch as much as needed horizontally.  The function returns to
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * you the maximum amount of space available horizontally, which you can
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * use if needed for UI placement.
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>In many cases this is not needed, you can just rely on the normal
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * view layout mechanisms to position your views within the full horizontal
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * space given to the input method.
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Note that this value can change dynamically, in particular when the
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * screen orientation changes.
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getMaxWidth() {
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return wm.getDefaultDisplay().getWidth();
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the currently active InputBinding for the input method, or
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * null if there is none.
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public InputBinding getCurrentInputBinding() {
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInputBinding;
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Retrieve the currently active InputConnection that is bound to
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the input method, or null if there is none.
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public InputConnection getCurrentInputConnection() {
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputConnection ic = mStartedInputConnection;
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ic != null) {
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ic;
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInputConnection;
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean getCurrentInputStarted() {
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInputStarted;
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public EditorInfo getCurrentInputEditorInfo() {
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInputEditorInfo;
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Re-evaluate whether the input method should be running in fullscreen
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * mode, and update its UI if this has changed since the last time it
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * was evaluated.  This will call {@link #onEvaluateFullscreenMode()} to
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * determine whether it should currently run in fullscreen mode.  You
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can use {@link #isFullscreenMode()} to determine if the input method
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is currently running in fullscreen mode.
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void updateFullscreenMode() {
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean isFullscreen = mShowInputRequested && onEvaluateFullscreenMode();
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean changed = mLastShowInputRequested != mShowInputRequested;
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mIsFullscreen != isFullscreen || !mFullscreenApplied) {
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            changed = true;
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIsFullscreen = isFullscreen;
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputConnection ic = getCurrentInputConnection();
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ic != null) ic.reportFullscreenMode(isFullscreen);
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFullscreenApplied = true;
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            initialize();
856105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)
857105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    mFullscreenArea.getLayoutParams();
858105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            if (isFullscreen) {
859105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                mFullscreenArea.setBackgroundDrawable(mThemeAttrs.getDrawable(
860105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                        com.android.internal.R.styleable.InputMethodService_imeFullscreenBackground));
861105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                lp.height = 0;
862105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                lp.weight = 1;
863105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            } else {
864105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                mFullscreenArea.setBackgroundDrawable(null);
865105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                lp.height = LinearLayout.LayoutParams.WRAP_CONTENT;
866105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                lp.weight = 0;
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
868105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            ((ViewGroup)mFullscreenArea.getParent()).updateViewLayout(
869105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    mFullscreenArea, lp);
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (isFullscreen) {
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mExtractView == null) {
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    View v = onCreateExtractTextView();
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (v != null) {
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        setExtractView(v);
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                startExtractingText(false);
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
879105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            updateExtractFrameVisibility();
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (changed) {
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onConfigureWindow(mWindow.getWindow(), isFullscreen,
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    !mShowInputRequested);
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLastShowInputRequested = mShowInputRequested;
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Update the given window's parameters for the given mode.  This is called
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when the window is first displayed and each time the fullscreen or
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * candidates only mode changes.
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The default implementation makes the layout for the window
895980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * MATCH_PARENT x MATCH_PARENT when in fullscreen mode, and
896980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * MATCH_PARENT x WRAP_CONTENT when in non-fullscreen mode.
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param win The input method's window.
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param isFullscreen If true, the window is running in fullscreen mode
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and intended to cover the entire application display.
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param isCandidatesOnly If true, the window is only showing the
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * candidates view and none of the rest of its UI.  This is mutually
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * exclusive with fullscreen mode.
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onConfigureWindow(Window win, boolean isFullscreen,
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean isCandidatesOnly) {
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isFullscreen) {
908980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy            mWindow.getWindow().setLayout(MATCH_PARENT, MATCH_PARENT);
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
910980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy            mWindow.getWindow().setLayout(MATCH_PARENT, WRAP_CONTENT);
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return whether the input method is <em>currently</em> running in
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * fullscreen mode.  This is the mode that was last determined and
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * applied by {@link #updateFullscreenMode()}.
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isFullscreenMode() {
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mIsFullscreen;
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Override this to control when the input method should run in
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * fullscreen mode.  The default implementation runs in fullsceen only
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when the screen is in landscape mode.  If you change what
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this returns, you will need to call {@link #updateFullscreenMode()}
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * yourself whenever the returned value may have changed to have it
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * re-evaluated and applied.
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onEvaluateFullscreenMode() {
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Configuration config = getResources().getConfiguration();
9332edd68260f26cbd6eddd0df16404bb6bcb22b3b6Leon Scroggins        if (config.orientation != Configuration.ORIENTATION_LANDSCAPE) {
9342edd68260f26cbd6eddd0df16404bb6bcb22b3b6Leon Scroggins            return false;
9352edd68260f26cbd6eddd0df16404bb6bcb22b3b6Leon Scroggins        }
9362edd68260f26cbd6eddd0df16404bb6bcb22b3b6Leon Scroggins        if (mInputEditorInfo != null
9372edd68260f26cbd6eddd0df16404bb6bcb22b3b6Leon Scroggins                && (mInputEditorInfo.imeOptions & EditorInfo.IME_FLAG_NO_FULLSCREEN) != 0) {
9382edd68260f26cbd6eddd0df16404bb6bcb22b3b6Leon Scroggins            return false;
9392edd68260f26cbd6eddd0df16404bb6bcb22b3b6Leon Scroggins        }
9402edd68260f26cbd6eddd0df16404bb6bcb22b3b6Leon Scroggins        return true;
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
944105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * Controls the visibility of the extracted text area.  This only applies
945105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * when the input method is in fullscreen mode, and thus showing extracted
946105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * text.  When false, the extracted text will not be shown, allowing some
947105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * of the application to be seen behind.  This is normally set for you
948105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * by {@link #onUpdateExtractingVisibility}.  This controls the visibility
949105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * of both the extracted text and candidate view; the latter since it is
950105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * not useful if there is no text to see.
951105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     */
952105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    public void setExtractViewShown(boolean shown) {
953105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (mExtractViewHidden == shown) {
954105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mExtractViewHidden = !shown;
955105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            updateExtractFrameVisibility();
956105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
957105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
958105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
959105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    /**
960105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * Return whether the fullscreen extract view is shown.  This will only
961105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * return true if {@link #isFullscreenMode()} returns true, and in that
962105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * case its value depends on the last call to
963105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * {@link #setExtractViewShown(boolean)}.  This effectively lets you
964105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * determine if the application window is entirely covered (when this
965105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * returns true) or if some part of it may be shown (if this returns
966105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * false, though if {@link #isFullscreenMode()} returns true in that case
967105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * then it is probably only a sliver of the application).
968105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     */
969105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    public boolean isExtractViewShown() {
970105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        return mIsFullscreen && !mExtractViewHidden;
971105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
972105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
973105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    void updateExtractFrameVisibility() {
974105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        int vis;
975105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (isFullscreenMode()) {
976105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            vis = mExtractViewHidden ? View.INVISIBLE : View.VISIBLE;
977105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mExtractFrame.setVisibility(View.VISIBLE);
978105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        } else {
979105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            vis = View.VISIBLE;
980105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mExtractFrame.setVisibility(View.GONE);
981105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
982105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        updateCandidatesVisibility(mCandidatesVisibility == View.VISIBLE);
983105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (mWindowWasVisible && mFullscreenArea.getVisibility() != vis) {
984105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            int animRes = mThemeAttrs.getResourceId(vis == View.VISIBLE
985105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    ? com.android.internal.R.styleable.InputMethodService_imeExtractEnterAnimation
986105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    : com.android.internal.R.styleable.InputMethodService_imeExtractExitAnimation,
987105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    0);
988105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            if (animRes != 0) {
989105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                mFullscreenArea.startAnimation(AnimationUtils.loadAnimation(
990105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                        this, animRes));
991105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            }
992105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
993105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        mFullscreenArea.setVisibility(vis);
994105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
995105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
996105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    /**
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Compute the interesting insets into your UI.  The default implementation
9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * uses the top of the candidates frame for the visible insets, and the
9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * top of the input frame for the content insets.  The default touchable
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * insets are {@link Insets#TOUCHABLE_INSETS_VISIBLE}.
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
1002105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * <p>Note that this method is not called when
1003105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * {@link #isExtractViewShown} returns true, since
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in that case the application is left as-is behind the input method and
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * not impacted by anything in its UI.
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param outInsets Fill in with the current UI insets.
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onComputeInsets(Insets outInsets) {
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int[] loc = mTmpLocation;
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mInputFrame.getVisibility() == View.VISIBLE) {
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInputFrame.getLocationInWindow(loc);
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1014105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            View decor = getWindow().getWindow().getDecorView();
1015105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            loc[1] = decor.getHeight();
1016105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
1017105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (isFullscreenMode()) {
1018105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            // In fullscreen mode, we never resize the underlying window.
1019105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            View decor = getWindow().getWindow().getDecorView();
1020105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            outInsets.contentTopInsets = decor.getHeight();
1021105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        } else {
1022105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            outInsets.contentTopInsets = loc[1];
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCandidatesFrame.getVisibility() == View.VISIBLE) {
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCandidatesFrame.getLocationInWindow(loc);
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outInsets.visibleTopInsets = loc[1];
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_VISIBLE;
1029fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown        outInsets.touchableRegion.setEmpty();
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Re-evaluate whether the soft input area should currently be shown, and
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * update its UI if this has changed since the last time it
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * was evaluated.  This will call {@link #onEvaluateInputViewShown()} to
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * determine whether the input view should currently be shown.  You
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can use {@link #isInputViewShown()} to determine if the input view
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is currently shown.
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void updateInputViewShown() {
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean isShown = mShowInputRequested && onEvaluateInputViewShown();
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mIsInputViewShown != isShown && mWindowVisible) {
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIsInputViewShown = isShown;
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInputFrame.setVisibility(isShown ? View.VISIBLE : View.GONE);
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mInputView == null) {
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                initialize();
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                View v = onCreateInputView();
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (v != null) {
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    setInputView(v);
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns true if we have been asked to show our input view.
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isShowInputRequested() {
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mShowInputRequested;
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return whether the soft input view is <em>currently</em> shown to the
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * user.  This is the state that was last determined and
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * applied by {@link #updateInputViewShown()}.
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isInputViewShown() {
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mIsInputViewShown && mWindowVisible;
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Override this to control when the soft input area should be shown to
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the user.  The default implementation only shows the input view when
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * there is no hard keyboard or the keyboard is hidden.  If you change what
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this returns, you will need to call {@link #updateInputViewShown()}
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * yourself whenever the returned value may have changed to have it
10778cbb4c6e30cff706a243599634aeb8fd9a818d92Gilles Debunne     * re-evaluated and applied.
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onEvaluateInputViewShown() {
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Configuration config = getResources().getConfiguration();
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return config.keyboard == Configuration.KEYBOARD_NOKEYS
10828710e76a897cd546a79ee4338a4147eeb9f3e068Ken Wakasa                || config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES;
10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Controls the visibility of the candidates display area.  By default
10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it is hidden.
10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setCandidatesViewShown(boolean shown) {
1090105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        updateCandidatesVisibility(shown);
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mShowInputRequested && mWindowVisible != shown) {
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If we are being asked to show the candidates view while the app
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // has not asked for the input view to be shown, then we need
10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // to update whether the window is shown.
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (shown) {
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                showWindow(false);
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hideWindow();
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1103105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    void updateCandidatesVisibility(boolean shown) {
1104105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        int vis = shown ? View.VISIBLE : getCandidatesHiddenVisibility();
1105105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (mCandidatesVisibility != vis) {
1106105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mCandidatesFrame.setVisibility(vis);
1107105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mCandidatesVisibility = vis;
1108105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
1109105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
1110105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the visibility mode (either {@link View#INVISIBLE View.INVISIBLE}
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or {@link View#GONE View.GONE}) of the candidates view when it is not
1114105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * shown.  The default implementation returns GONE when
1115105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * {@link #isExtractViewShown} returns true,
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * otherwise VISIBLE.  Be careful if you change this to return GONE in
11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * other situations -- if showing or hiding the candidates view causes
11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * your window to resize, this can cause temporary drawing artifacts as
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the resize takes place.
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getCandidatesHiddenVisibility() {
1122105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        return isExtractViewShown() ? View.GONE : View.INVISIBLE;
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showStatusIcon(int iconResId) {
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStatusIcon = iconResId;
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mImm.showStatusIcon(mToken, getPackageName(), iconResId);
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void hideStatusIcon() {
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStatusIcon = 0;
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mImm.hideStatusIcon(mToken);
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Force switch to a new input method, as identified by <var>id</var>.  This
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * input method will be destroyed, and the requested one started on the
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * current input field.
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param id Unique identifier of the new input method ot start.
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void switchInputMethod(String id) {
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mImm.setInputMethod(mToken, id);
11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setExtractView(View view) {
11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mExtractFrame.removeAllViews();
11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mExtractFrame.addView(view, new FrameLayout.LayoutParams(
1149980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy                ViewGroup.LayoutParams.MATCH_PARENT,
1150980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy                ViewGroup.LayoutParams.MATCH_PARENT));
11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mExtractView = view;
11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (view != null) {
11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractEditText = (ExtractEditText)view.findViewById(
11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    com.android.internal.R.id.inputExtractEditText);
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractEditText.setIME(this);
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractAction = (Button)view.findViewById(
11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    com.android.internal.R.id.inputExtractAction);
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mExtractAction != null) {
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mExtractAccessories = (ViewGroup)view.findViewById(
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        com.android.internal.R.id.inputExtractAccessories);
11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            startExtractingText(false);
11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractEditText = null;
11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractAccessories = null;
11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractAction = null;
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Replaces the current candidates view with a new one.  You only need to
11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * call this when dynamically changing the view; normally, you should
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implement {@link #onCreateCandidatesView()} and create your view when
11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * first needed by the input method.
11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setCandidatesView(View view) {
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCandidatesFrame.removeAllViews();
11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCandidatesFrame.addView(view, new FrameLayout.LayoutParams(
1179980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy                ViewGroup.LayoutParams.MATCH_PARENT,
11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ViewGroup.LayoutParams.WRAP_CONTENT));
11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Replaces the current input view with a new one.  You only need to
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * call this when dynamically changing the view; normally, you should
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implement {@link #onCreateInputView()} and create your view when
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * first needed by the input method.
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setInputView(View view) {
11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputFrame.removeAllViews();
11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputFrame.addView(view, new FrameLayout.LayoutParams(
1192980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy                ViewGroup.LayoutParams.MATCH_PARENT,
11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ViewGroup.LayoutParams.WRAP_CONTENT));
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputView = view;
11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called by the framework to create the layout for showing extacted text.
11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Only called when in fullscreen mode.  The returned view hierarchy must
12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * have an {@link ExtractEditText} whose ID is
12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.R.id#inputExtractEditText}.
12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View onCreateExtractTextView() {
12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInflater.inflate(
12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                com.android.internal.R.layout.input_method_extract_view, null);
12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create and return the view hierarchy used to show candidates.  This will
12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be called once, when the candidates are first displayed.  You can return
12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * null to have no candidates view; the default implementation returns null.
12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>To control when the candidates view is displayed, use
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #setCandidatesViewShown(boolean)}.
12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * To change the candidates view after the first one is created by this
12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * function, use {@link #setCandidatesView(View)}.
12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View onCreateCandidatesView() {
12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create and return the view hierarchy used for the input area (such as
12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a soft keyboard).  This will be called once, when the input area is
12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * first displayed.  You can return null to have no input area; the default
12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implementation returns null.
12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>To control when the input view is displayed, implement
12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #onEvaluateInputViewShown()}.
12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * To change the input view after the first one is created by this
12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * function, use {@link #setInputView(View)}.
12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View onCreateInputView() {
12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the input view is being shown and input has started on
12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a new editor.  This will always be called after {@link #onStartInput},
12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * allowing you to do your general setup there and just view-specific
12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * setup here.  You are guaranteed that {@link #onCreateInputView()} will
12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * have been called some time before this function is called.
12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param info Description of the type of text being edited.
12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param restarting Set to true if we are restarting input on the
12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * same text field as before.
12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onStartInputView(EditorInfo info, boolean restarting) {
12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the input view is being hidden from the user.  This will
12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be called either prior to hiding the window, or prior to switching to
12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * another target for editing.
12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The default
12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implementation uses the InputConnection to clear any active composing
12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * text; you can override this (not calling the base class implementation)
12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to perform whatever behavior you would like.
12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12614df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * @param finishingInput If true, {@link #onFinishInput} will be
12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * called immediately after.
12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onFinishInputView(boolean finishingInput) {
12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!finishingInput) {
12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputConnection ic = getCurrentInputConnection();
12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ic != null) {
12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ic.finishComposingText();
12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when only the candidates view has been shown for showing
12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * processing as the user enters text through a hard keyboard.
12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This will always be called after {@link #onStartInput},
12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * allowing you to do your general setup there and just view-specific
12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * setup here.  You are guaranteed that {@link #onCreateCandidatesView()}
12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will have been called some time before this function is called.
12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Note that this will <em>not</em> be called when the input method
12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is running in full editing mode, and thus receiving
12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #onStartInputView} to initiate that operation.  This is only
12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for the case when candidates are being shown while the input method
12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * editor is hidden but wants to show its candidates UI as text is
12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * entered through some other mechanism.
12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param info Description of the type of text being edited.
12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param restarting Set to true if we are restarting input on the
12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * same text field as before.
12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onStartCandidatesView(EditorInfo info, boolean restarting) {
12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the candidates view is being hidden from the user.  This will
12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be called either prior to hiding the window, or prior to switching to
12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * another target for editing.
12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The default
13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implementation uses the InputConnection to clear any active composing
13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * text; you can override this (not calling the base class implementation)
13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to perform whatever behavior you would like.
13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
13054df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * @param finishingInput If true, {@link #onFinishInput} will be
13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * called immediately after.
13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onFinishCandidatesView(boolean finishingInput) {
13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!finishingInput) {
13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputConnection ic = getCurrentInputConnection();
13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ic != null) {
13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ic.finishComposingText();
13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The system has decided that it may be time to show your input method.
13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is called due to a corresponding call to your
13204df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * {@link InputMethod#showSoftInput InputMethod.showSoftInput()}
13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * method.  The default implementation uses
13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #onEvaluateInputViewShown()}, {@link #onEvaluateFullscreenMode()},
13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and the current configuration to decide whether the input view should
13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be shown at this point.
13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param flags Provides additional information about the show request,
13274df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * as per {@link InputMethod#showSoftInput InputMethod.showSoftInput()}.
13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param configChange This is true if we are re-showing due to a
13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * configuration change.
13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns true to indicate that the window should be shown.
13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onShowInputRequested(int flags, boolean configChange) {
13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!onEvaluateInputViewShown()) {
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((flags&InputMethod.SHOW_EXPLICIT) == 0) {
13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!configChange && onEvaluateFullscreenMode()) {
13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Don't show if this is not explicitly requested by the user and
13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // the input method is fullscreen.  That would be too disruptive.
13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // However, we skip this change for a config change, since if
13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // the IME is already shown we do want to go into fullscreen
13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // mode at this point.
13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return false;
13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Configuration config = getResources().getConfiguration();
13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (config.keyboard != Configuration.KEYBOARD_NOKEYS) {
13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // And if the device has a hard keyboard, even if it is
13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // currently hidden, don't show the input method implicitly.
13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // These kinds of devices don't need it that much.
13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return false;
13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((flags&InputMethod.SHOW_FORCED) != 0) {
13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mShowInputForced = true;
13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showWindow(boolean showInput) {
13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DEBUG) Log.v(TAG, "Showing window: showInput=" + showInput
13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mShowInputRequested=" + mShowInputRequested
13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mWindowAdded=" + mWindowAdded
13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mWindowCreated=" + mWindowCreated
13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mWindowVisible=" + mWindowVisible
13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mInputStarted=" + mInputStarted);
1366105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
1367105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (mInShowWindow) {
1368105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            Log.w(TAG, "Re-entrance in to showWindow");
1369105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            return;
1370105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
1371105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
1372105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        try {
1373105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mWindowWasVisible = mWindowVisible;
1374105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mInShowWindow = true;
1375105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            showWindowInner(showInput);
1376105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        } finally {
1377105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mWindowWasVisible = true;
1378105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mInShowWindow = false;
1379105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
1380105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
138106487a58be22b100daf3f950b9a1d25c3ea42aa2satok
1382105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    void showWindowInner(boolean showInput) {
13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean doShowInput = false;
13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean wasVisible = mWindowVisible;
13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWindowVisible = true;
13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mShowInputRequested) {
13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mInputStarted) {
13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (showInput) {
13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    doShowInput = true;
13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mShowInputRequested = true;
13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            showInput = true;
13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
139606487a58be22b100daf3f950b9a1d25c3ea42aa2satok
13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DEBUG) Log.v(TAG, "showWindow: updating UI");
13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        initialize();
13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updateFullscreenMode();
14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updateInputViewShown();
14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mWindowAdded || !mWindowCreated) {
14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWindowAdded = true;
14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWindowCreated = true;
14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            initialize();
14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "CALL: onCreateCandidatesView");
14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            View v = onCreateCandidatesView();
14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "showWindow: candidates=" + v);
14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (v != null) {
14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setCandidatesView(v);
14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mShowInputRequested) {
14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mInputViewStarted) {
14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (DEBUG) Log.v(TAG, "CALL: onStartInputView");
14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mInputViewStarted = true;
14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                onStartInputView(mInputEditorInfo, false);
14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!mCandidatesViewStarted) {
14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "CALL: onStartCandidatesView");
14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCandidatesViewStarted = true;
14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onStartCandidatesView(mInputEditorInfo, false);
14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (doShowInput) {
14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            startExtractingText(false);
14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
142806487a58be22b100daf3f950b9a1d25c3ea42aa2satok
14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!wasVisible) {
14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "showWindow: showing!");
1431857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato            mImm.setImeWindowStatus(mToken, IME_ACTIVE, mBackDisposition);
14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onWindowShown();
14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWindow.show();
14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
143606487a58be22b100daf3f950b9a1d25c3ea42aa2satok
14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void hideWindow() {
14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mInputViewStarted) {
14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "CALL: onFinishInputView");
14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onFinishInputView(false);
14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (mCandidatesViewStarted) {
14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "CALL: onFinishCandidatesView");
14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onFinishCandidatesView(false);
14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputViewStarted = false;
14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCandidatesViewStarted = false;
1447857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato        mImm.setImeWindowStatus(mToken, 0, mBackDisposition);
14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mWindowVisible) {
14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWindow.hide();
14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWindowVisible = false;
14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onWindowHidden();
1452105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mWindowWasVisible = false;
14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
145506487a58be22b100daf3f950b9a1d25c3ea42aa2satok
14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the input method window has been shown to the user, after
14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * previously not being visible.  This is done after all of the UI setup
14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for the window has occurred (creating its views etc).
14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onWindowShown() {
14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the input method window has been hidden from the user,
14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after previously being visible.
14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onWindowHidden() {
14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when a new client has bound to the input method.  This
14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * may be followed by a series of {@link #onStartInput(EditorInfo, boolean)}
14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and {@link #onFinishInput()} calls as the user navigates through its
14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * UI.  Upon this call you know that {@link #getCurrentInputBinding}
14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and {@link #getCurrentInputConnection} return valid objects.
14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onBindInput() {
14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the previous bound client is no longer associated
14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * with the input method.  After returning {@link #getCurrentInputBinding}
14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and {@link #getCurrentInputConnection} will no longer return
14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * valid objects.
14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onUnbindInput() {
14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called to inform the input method that text input has started in an
14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * editor.  You should use this callback to initialize the state of your
14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * input to match the state of the editor given to it.
14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param attribute The attributes of the editor that input is starting
14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in.
14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param restarting Set to true if input is restarting in the same
14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * editor such as because the application has changed the text in
14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the editor.  Otherwise will be false, indicating this is a new
15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * session with the editor.
15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onStartInput(EditorInfo attribute, boolean restarting) {
15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void doFinishInput() {
15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mInputViewStarted) {
15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "CALL: onFinishInputView");
15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onFinishInputView(true);
15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (mCandidatesViewStarted) {
15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "CALL: onFinishCandidatesView");
15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onFinishCandidatesView(true);
15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputViewStarted = false;
15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCandidatesViewStarted = false;
15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mInputStarted) {
15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "CALL: onFinishInput");
15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onFinishInput();
15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputStarted = false;
15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStartedInputConnection = null;
15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCurCompletions = null;
15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15234df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project
15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void doStartInput(InputConnection ic, EditorInfo attribute, boolean restarting) {
15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!restarting) {
15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doFinishInput();
15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputStarted = true;
15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStartedInputConnection = ic;
15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputEditorInfo = attribute;
15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        initialize();
15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DEBUG) Log.v(TAG, "CALL: onStartInput");
15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        onStartInput(attribute, restarting);
15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mWindowVisible) {
15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mShowInputRequested) {
15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (DEBUG) Log.v(TAG, "CALL: onStartInputView");
15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mInputViewStarted = true;
15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                onStartInputView(mInputEditorInfo, restarting);
15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                startExtractingText(true);
15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (mCandidatesVisibility == View.VISIBLE) {
15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (DEBUG) Log.v(TAG, "CALL: onStartCandidatesView");
15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mCandidatesViewStarted = true;
15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                onStartCandidatesView(mInputEditorInfo, restarting);
15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called to inform the input method that text input has finished in
15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the last editor.  At this point there may be a call to
15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #onStartInput(EditorInfo, boolean)} to perform input in a
15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * new editor, or the input method may be left idle.  This method is
15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <em>not</em> called when input restarts in the same editor.
15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The default
15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implementation uses the InputConnection to clear any active composing
15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * text; you can override this (not calling the base class implementation)
15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to perform whatever behavior you would like.
15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onFinishInput() {
15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputConnection ic = getCurrentInputConnection();
15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ic != null) {
15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ic.finishComposingText();
15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the application has reported auto-completion candidates that
15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it would like to have the input method displayed.  Typically these are
15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * only used when an input method is running in full-screen mode, since
15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * otherwise the user can see and interact with the pop-up window of
15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * completions shown by the application.
15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The default implementation here does nothing.
15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onDisplayCompletions(CompletionInfo[] completions) {
15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the application has reported new extracted text to be shown
15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * due to changes in its current text state.  The default implementation
15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * here places the new text in the extract edit text, when the input
15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * method is running in fullscreen mode.
15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onUpdateExtractedText(int token, ExtractedText text) {
15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mExtractedToken != token) {
15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1589b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project        if (text != null) {
1590b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project            if (mExtractEditText != null) {
1591b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project                mExtractedText = text;
1592b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project                mExtractEditText.setExtractedText(text);
1593b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project            }
15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the application has reported a new selection region of
15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the text.  This is called whether or not the input method has requested
16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * extracted text updates, although if so it will not receive this call
16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if the extracted text has changed as well.
16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The default implementation takes care of updating the cursor in
16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the extract text, if it is being shown.
16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onUpdateSelection(int oldSelStart, int oldSelEnd,
16079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int newSelStart, int newSelEnd,
16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int candidatesStart, int candidatesEnd) {
16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ExtractEditText eet = mExtractEditText;
1610c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        if (eet != null && isFullscreenMode() && mExtractedText != null) {
16119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int off = mExtractedText.startOffset;
16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            eet.startInternalChanges();
1613c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            newSelStart -= off;
1614c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            newSelEnd -= off;
1615c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            final int len = eet.getText().length();
1616c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            if (newSelStart < 0) newSelStart = 0;
1617c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            else if (newSelStart > len) newSelStart = len;
1618c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            if (newSelEnd < 0) newSelEnd = 0;
1619c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            else if (newSelEnd > len) newSelEnd = len;
1620c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            eet.setSelection(newSelStart, newSelEnd);
16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            eet.finishInternalChanges();
16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1626863fcd62171e55bc9f2105d9fb5877df982454d8satok     * Called when the user tapped or clicked a text view.
1627863fcd62171e55bc9f2105d9fb5877df982454d8satok     * IMEs can't rely on this method being called because this was not part of the original IME
1628863fcd62171e55bc9f2105d9fb5877df982454d8satok     * protocol, so applications with custom text editing written before this method appeared will
1629863fcd62171e55bc9f2105d9fb5877df982454d8satok     * not call to inform the IME of this interaction.
1630863fcd62171e55bc9f2105d9fb5877df982454d8satok     * @param focusChanged true if the user changed the focused view by this click.
1631863fcd62171e55bc9f2105d9fb5877df982454d8satok     */
1632863fcd62171e55bc9f2105d9fb5877df982454d8satok    public void onViewClicked(boolean focusChanged) {
1633863fcd62171e55bc9f2105d9fb5877df982454d8satok    }
1634863fcd62171e55bc9f2105d9fb5877df982454d8satok
1635863fcd62171e55bc9f2105d9fb5877df982454d8satok    /**
16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the application has reported a new location of its text
16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * cursor.  This is only called if explicitly requested by the input method.
16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The default implementation does nothing.
16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onUpdateCursor(Rect newCursor) {
16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Close this input method's soft input area, removing it from the display.
16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The input method will continue running, but the user can no longer use
16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it to generate input by touching the screen.
16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param flags Provides additional operating flags.  Currently may be
16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * 0 or have the {@link InputMethodManager#HIDE_IMPLICIT_ONLY
16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * InputMethodManager.HIDE_IMPLICIT_ONLY} bit set.
16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16514df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    public void requestHideSelf(int flags) {
16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mImm.hideSoftInputFromInputMethod(mToken, flags);
16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
16564df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * Show the input method. This is a call back to the
16574df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * IMF to handle showing the input method.
16584df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * Close this input method's soft input area, removing it from the display.
16594df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * The input method will continue running, but the user can no longer use
16604df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * it to generate input by touching the screen.
16614df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * @param flags Provides additional operating flags.  Currently may be
16624df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * 0 or have the {@link InputMethodManager#SHOW_FORCED
16634df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * InputMethodManager.} bit set.
16644df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     */
16654df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    private void requestShowSelf(int flags) {
16664df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        mImm.showSoftInputFromInputMethod(mToken, flags);
16674df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    }
16684df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project
166983fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn    private boolean handleBack(boolean doIt) {
167083fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        if (mShowInputRequested) {
167183fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            // If the soft input area is shown, back closes it and we
167283fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            // consume the back key.
167383fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            if (doIt) requestHideSelf(0);
167483fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            return true;
167583fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        } else if (mWindowVisible) {
167683fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            if (mCandidatesVisibility == View.VISIBLE) {
167783fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                // If we are showing candidates even if no input area, then
167883fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                // hide them.
167983fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                if (doIt) setCandidatesViewShown(false);
168083fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            } else {
168183fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                // If we have the window visible for some other reason --
168283fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                // most likely to show candidates -- then just get rid
168383fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                // of it.  This really shouldn't happen, but just in case...
168483fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                if (doIt) hideWindow();
168583fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            }
168683fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            return true;
168783fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        }
168883fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        return false;
168983fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn    }
169083fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn
16914df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    /**
16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Override this to intercept key down events before they are processed by the
16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * application.  If you return true, the application will not itself
16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * process the event.  If you return true, the normal application processing
16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will occur as if the IME had not seen the event at all.
16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The default implementation intercepts {@link KeyEvent#KEYCODE_BACK
169883fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * KeyEvent.KEYCODE_BACK} if the IME is currently shown, to
169983fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * possibly hide it when the key goes up (if not canceled or long pressed).  In
170083fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * addition, in fullscreen mode only, it will consume DPAD movement
17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * events to move the cursor in the extracted text view, not allowing
17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * them to perform navigation in the underlying application.
17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onKeyDown(int keyCode, KeyEvent event) {
170583fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
170683fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            if (handleBack(false)) {
170783fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                event.startTracking();
17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
171083fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            return false;
17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return doMovementKey(keyCode, event, MOVEMENT_DOWN);
17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
171683fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * Default implementation of {@link KeyEvent.Callback#onKeyLongPress(int, KeyEvent)
171783fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle
171883fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * the event).
171983fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     */
172083fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn    public boolean onKeyLongPress(int keyCode, KeyEvent event) {
172183fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        return false;
172283fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn    }
172383fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn
172483fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn    /**
17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Override this to intercept special key multiple events before they are
17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * processed by the
17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * application.  If you return true, the application will not itself
17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * process the event.  If you return true, the normal application processing
17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will occur as if the IME had not seen the event at all.
17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The default implementation always returns false, except when
17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in fullscreen mode, where it will consume DPAD movement
17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * events to move the cursor in the extracted text view, not allowing
17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * them to perform navigation in the underlying application.
17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onKeyMultiple(int keyCode, int count, KeyEvent event) {
17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return doMovementKey(keyCode, event, count);
17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Override this to intercept key up events before they are processed by the
17429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * application.  If you return true, the application will not itself
17439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * process the event.  If you return true, the normal application processing
17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will occur as if the IME had not seen the event at all.
17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
174683fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * <p>The default implementation intercepts {@link KeyEvent#KEYCODE_BACK
174783fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * KeyEvent.KEYCODE_BACK} to hide the current IME UI if it is shown.  In
174883fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * addition, in fullscreen mode only, it will consume DPAD movement
17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * events to move the cursor in the extracted text view, not allowing
17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * them to perform navigation in the underlying application.
17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onKeyUp(int keyCode, KeyEvent event) {
175383fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.isTracking()
175483fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                && !event.isCanceled()) {
175583fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            return handleBack(true);
175683fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        }
175783fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn
17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return doMovementKey(keyCode, event, MOVEMENT_UP);
17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1761ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    @Override
17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onTrackballEvent(MotionEvent event) {
17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onAppPrivateCommand(String action, Bundle data) {
17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17694df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    /**
17704df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * Handle a request by the system to toggle the soft input area.
17714df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     */
17724df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    private void onToggleSoftInput(int showFlags, int hideFlags) {
17734df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        if (DEBUG) Log.v(TAG, "toggleSoftInput()");
17744df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        if (isInputViewShown()) {
17754df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            requestHideSelf(hideFlags);
17764df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        } else {
17774df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            requestShowSelf(showFlags);
17784df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        }
17794df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    }
17804df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project
17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MOVEMENT_DOWN = -1;
17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MOVEMENT_UP = -2;
17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void reportExtractedMovement(int keyCode, int count) {
17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int dx = 0, dy = 0;
17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (keyCode) {
17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case KeyEvent.KEYCODE_DPAD_LEFT:
17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dx = -count;
17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case KeyEvent.KEYCODE_DPAD_RIGHT:
17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dx = count;
17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case KeyEvent.KEYCODE_DPAD_UP:
17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dy = -count;
17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case KeyEvent.KEYCODE_DPAD_DOWN:
17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dy = count;
17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1800ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok        onExtractedCursorMovement(dx, dy);
18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean doMovementKey(int keyCode, KeyEvent event, int count) {
18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ExtractEditText eet = mExtractEditText;
1805105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (isExtractViewShown() && isInputViewShown() && eet != null) {
18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If we are in fullscreen mode, the cursor will move around
18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // the extract edit text, but should NOT cause focus to move
18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // to other fields.
18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            MovementMethod movement = eet.getMovementMethod();
18109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Layout layout = eet.getLayout();
18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (movement != null && layout != null) {
18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // We want our own movement method to handle the key, so the
18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // cursor will properly move in our own word wrapping.
18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (count == MOVEMENT_DOWN) {
18159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (movement.onKeyDown(eet,
18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            (Spannable)eet.getText(), keyCode, event)) {
18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        reportExtractedMovement(keyCode, 1);
18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return true;
18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (count == MOVEMENT_UP) {
18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (movement.onKeyUp(eet,
18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            (Spannable)eet.getText(), keyCode, event)) {
18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return true;
18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (movement.onKeyOther(eet, (Spannable)eet.getText(), event)) {
18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        reportExtractedMovement(keyCode, count);
18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
1829105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                        KeyEvent down = KeyEvent.changeAction(event, KeyEvent.ACTION_DOWN);
18309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (movement.onKeyDown(eet,
18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                (Spannable)eet.getText(), keyCode, down)) {
1832105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                            KeyEvent up = KeyEvent.changeAction(event, KeyEvent.ACTION_UP);
18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            movement.onKeyUp(eet,
18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    (Spannable)eet.getText(), keyCode, up);
18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            while (--count > 0) {
18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                movement.onKeyDown(eet,
18379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        (Spannable)eet.getText(), keyCode, down);
18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                movement.onKeyUp(eet,
18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        (Spannable)eet.getText(), keyCode, up);
18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            reportExtractedMovement(keyCode, count);
18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
18449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
18469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Regardless of whether the movement method handled the key,
18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // we never allow DPAD navigation to the application.
18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (keyCode) {
18499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case KeyEvent.KEYCODE_DPAD_LEFT:
18509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case KeyEvent.KEYCODE_DPAD_RIGHT:
18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case KeyEvent.KEYCODE_DPAD_UP:
18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case KeyEvent.KEYCODE_DPAD_DOWN:
18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return true;
18549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Send the given key event code (as defined by {@link KeyEvent}) to the
18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * current input connection is a key down + key up event pair.  The sent
18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * events have {@link KeyEvent#FLAG_SOFT_KEYBOARD KeyEvent.FLAG_SOFT_KEYBOARD}
18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * set, so that the recipient can identify them as coming from a software
18659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * input method, and
18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link KeyEvent#FLAG_KEEP_TOUCH_MODE KeyEvent.FLAG_KEEP_TOUCH_MODE}, so
18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that they don't impact the current touch mode of the UI.
18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param keyEventCode The raw key code to send, as defined by
18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link KeyEvent}.
18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void sendDownUpKeyEvents(int keyEventCode) {
18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputConnection ic = getCurrentInputConnection();
18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ic == null) return;
18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long eventTime = SystemClock.uptimeMillis();
18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ic.sendKeyEvent(new KeyEvent(eventTime, eventTime,
18776b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                KeyEvent.ACTION_DOWN, keyEventCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));
18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ic.sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime,
18806b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                KeyEvent.ACTION_UP, keyEventCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));
18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Ask the input target to execute its default action via
18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link InputConnection#performEditorAction
18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * InputConnection.performEditorAction()}.
18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param fromEnterKey If true, this will be executed as if the user had
18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * pressed an enter key on the keyboard, that is it will <em>not</em>
18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be done if the editor has set {@link EditorInfo#IME_FLAG_NO_ENTER_ACTION
18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * EditorInfo.IME_FLAG_NO_ENTER_ACTION}.  If false, the action will be
18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * sent regardless of how the editor has set that flag.
18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a boolean indicating whether an action has been sent.
18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If false, either the editor did not specify a default action or it
18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * does not want an action from the enter key.  If true, the action was
18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * sent (or there was no input connection at all).
18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean sendDefaultEditorAction(boolean fromEnterKey) {
19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        EditorInfo ei = getCurrentInputEditorInfo();
19029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ei != null &&
19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (!fromEnterKey || (ei.imeOptions &
19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        EditorInfo.IME_FLAG_NO_ENTER_ACTION) == 0) &&
19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (ei.imeOptions & EditorInfo.IME_MASK_ACTION) !=
19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    EditorInfo.IME_ACTION_NONE) {
19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If the enter key was pressed, and the editor has a default
19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // action associated with pressing enter, then send it that
19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // explicit action instead of the key event.
19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputConnection ic = getCurrentInputConnection();
19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ic != null) {
19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ic.performEditorAction(ei.imeOptions&EditorInfo.IME_MASK_ACTION);
19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
19159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Send the given UTF-16 character to the current input connection.  Most
19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * characters will be delivered simply by calling
19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link InputConnection#commitText InputConnection.commitText()} with
19249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the character; some, however, may be handled different.  In particular,
19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the enter character ('\n') will either be delivered as an action code
19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or a raw key event, as appropriate.
19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param charCode The UTF-16 character code to send.
19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void sendKeyChar(char charCode) {
19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (charCode) {
19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case '\n': // Apps may be listening to an enter key to perform an action
19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!sendDefaultEditorAction(true)) {
19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sendDownUpKeyEvents(KeyEvent.KEYCODE_ENTER);
19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
19369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
19379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            default:
19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Make sure that digits go through any text watcher on the client side.
19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (charCode >= '0' && charCode <= '9') {
19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sendDownUpKeyEvents(charCode - '0' + KeyEvent.KEYCODE_0);
19419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    InputConnection ic = getCurrentInputConnection();
19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (ic != null) {
19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ic.commitText(String.valueOf((char) charCode), 1);
19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is called when the user has moved the cursor in the extracted
19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * text view, when running in fullsreen mode.  The default implementation
19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * performs the corresponding selection change on the underlying text
19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * editor.
19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onExtractedSelectionChanged(int start, int end) {
19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputConnection conn = getCurrentInputConnection();
19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (conn != null) {
19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            conn.setSelection(start, end);
19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is called when the user has clicked on the extracted text view,
19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when running in fullscreen mode.  The default implementation hides
19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the candidates view when this happens, but only if the extracted text
19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * editor has a vertical scroll bar because its text doesn't fit.
19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Re-implement this to provide whatever behavior you want.
19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onExtractedTextClicked() {
19729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mExtractEditText == null) {
19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
19749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mExtractEditText.hasVerticalScrollBar()) {
19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setCandidatesViewShown(false);
19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is called when the user has performed a cursor movement in the
19829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * extracted text view, when it is running in fullscreen mode.  The default
19839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implementation hides the candidates view when a vertical movement
19849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * happens, but only if the extracted text editor has a vertical scroll bar
19859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * because its text doesn't fit.
19869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Re-implement this to provide whatever behavior you want.
19879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param dx The amount of cursor movement in the x dimension.
19889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param dy The amount of cursor movement in the y dimension.
19899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onExtractedCursorMovement(int dx, int dy) {
19919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mExtractEditText == null || dy == 0) {
19929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
19939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mExtractEditText.hasVerticalScrollBar()) {
19959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setCandidatesViewShown(false);
19969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
20009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is called when the user has selected a context menu item from the
20019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * extracted text view, when running in fullscreen mode.  The default
20029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implementation sends this action to the current InputConnection's
20039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link InputConnection#performContextMenuAction(int)}, for it
20049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to be processed in underlying "real" editor.  Re-implement this to
20059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * provide whatever behavior you want.
20069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
20079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onExtractTextContextMenuItem(int id) {
20089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputConnection ic = getCurrentInputConnection();
20099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ic != null) {
20109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ic.performContextMenuAction(id);
20119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
20139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
20169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return text that can be used as a button label for the given
20179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link EditorInfo#imeOptions EditorInfo.imeOptions}.  Returns null
20189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if there is no action requested.  Note that there is no guarantee that
20199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the returned text will be relatively short, so you probably do not
20209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * want to use it as text on a soft keyboard key label.
20219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
20229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param imeOptions The value from @link EditorInfo#imeOptions EditorInfo.imeOptions}.
20239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
20249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a label to use, or null if there is no action.
20259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
20269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CharSequence getTextForImeAction(int imeOptions) {
20279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (imeOptions&EditorInfo.IME_MASK_ACTION) {
20289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EditorInfo.IME_ACTION_NONE:
20299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return null;
20309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EditorInfo.IME_ACTION_GO:
20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getText(com.android.internal.R.string.ime_action_go);
20329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EditorInfo.IME_ACTION_SEARCH:
20339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getText(com.android.internal.R.string.ime_action_search);
20349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EditorInfo.IME_ACTION_SEND:
20359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getText(com.android.internal.R.string.ime_action_send);
20369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EditorInfo.IME_ACTION_NEXT:
20379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getText(com.android.internal.R.string.ime_action_next);
20384df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            case EditorInfo.IME_ACTION_DONE:
20394df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                return getText(com.android.internal.R.string.ime_action_done);
2040dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn            case EditorInfo.IME_ACTION_PREVIOUS:
2041dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn                return getText(com.android.internal.R.string.ime_action_previous);
20429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            default:
20439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getText(com.android.internal.R.string.ime_action_default);
20449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2048105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * Called when the fullscreen-mode extracting editor info has changed,
2049105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * to determine whether the extracting (extract text and candidates) portion
2050105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * of the UI should be shown.  The standard implementation hides or shows
2051105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * the extract area depending on whether it makes sense for the
2052105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * current editor.  In particular, a {@link InputType#TYPE_NULL}
2053105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * input type or {@link EditorInfo#IME_FLAG_NO_EXTRACT_UI} flag will
2054105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * turn off the extract area since there is no text to be shown.
2055105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     */
2056105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    public void onUpdateExtractingVisibility(EditorInfo ei) {
2057105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (ei.inputType == InputType.TYPE_NULL ||
2058105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                (ei.imeOptions&EditorInfo.IME_FLAG_NO_EXTRACT_UI) != 0) {
2059105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            // No reason to show extract UI!
2060105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            setExtractViewShown(false);
2061105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            return;
2062105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
2063105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
2064105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        setExtractViewShown(true);
2065105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
2066105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
2067105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    /**
2068105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * Called when the fullscreen-mode extracting editor info has changed,
2069105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * to update the state of its UI such as the action buttons shown.
2070105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * You do not need to deal with this if you are using the standard
20719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * full screen extract UI.  If replacing it, you will need to re-implement
2072105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * this to put the appropriate action button in your own UI and handle it,
2073105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * and perform any other changes.
2074105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     *
2075105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * <p>The standard implementation turns on or off its accessory area
2076105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * depending on whether there is an action button, and hides or shows
2077105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * the entire extract area depending on whether it makes sense for the
2078105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * current editor.  In particular, a {@link InputType#TYPE_NULL} or
2079105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * {@link InputType#TYPE_TEXT_VARIATION_FILTER} input type will turn off the
2080105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * extract area since there is no text to be shown.
20819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2082105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    public void onUpdateExtractingViews(EditorInfo ei) {
2083105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (!isExtractViewShown()) {
2084105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            return;
2085105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
2086105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
20879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mExtractAccessories == null) {
20889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
20899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final boolean hasAction = ei.actionLabel != null || (
20919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (ei.imeOptions&EditorInfo.IME_MASK_ACTION) != EditorInfo.IME_ACTION_NONE &&
2092105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                (ei.imeOptions&EditorInfo.IME_FLAG_NO_ACCESSORY_ACTION) == 0 &&
2093105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                ei.inputType != InputType.TYPE_NULL);
20949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (hasAction) {
20959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractAccessories.setVisibility(View.VISIBLE);
209659eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik            if (mExtractAction != null) {
209759eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik                if (ei.actionLabel != null) {
209859eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik                    mExtractAction.setText(ei.actionLabel);
209959eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik                } else {
210059eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik                    mExtractAction.setText(getTextForImeAction(ei.imeOptions));
210159eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik                }
210259eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik                mExtractAction.setOnClickListener(mActionClickListener);
21039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
21049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
21059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractAccessories.setVisibility(View.GONE);
210659eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik            if (mExtractAction != null) {
210759eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik                mExtractAction.setOnClickListener(null);
210859eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik            }
21099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
21139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is called when, while currently displayed in extract mode, the
21149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * current input target changes.  The default implementation will
21159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * auto-hide the IME if the new target is not a full editor, since this
21169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can be an confusing experience for the user.
21179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
21189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onExtractingInputChanged(EditorInfo ei) {
21199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ei.inputType == InputType.TYPE_NULL) {
21204df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            requestHideSelf(InputMethodManager.HIDE_NOT_ALWAYS);
21219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void startExtractingText(boolean inputChanged) {
21259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ExtractEditText eet = mExtractEditText;
21269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (eet != null && getCurrentInputStarted()
21279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && isFullscreenMode()) {
21289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractedToken++;
21299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ExtractedTextRequest req = new ExtractedTextRequest();
21309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            req.token = mExtractedToken;
21319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            req.flags = InputConnection.GET_TEXT_WITH_STYLES;
21329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            req.hintMaxLines = 10;
21339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            req.hintMaxChars = 10000;
2134ba4d93fcd76fdd7c8368e23c7faf9a20684e51a0Amith Yamasani            InputConnection ic = getCurrentInputConnection();
2135ba4d93fcd76fdd7c8368e23c7faf9a20684e51a0Amith Yamasani            mExtractedText = ic == null? null
2136ba4d93fcd76fdd7c8368e23c7faf9a20684e51a0Amith Yamasani                    : ic.getExtractedText(req, InputConnection.GET_EXTRACTED_TEXT_MONITOR);
2137a8b00c8801be8e7bd21ddab64a3cde9b5ff2984aAmith Yamasani            if (mExtractedText == null || ic == null) {
2138a8b00c8801be8e7bd21ddab64a3cde9b5ff2984aAmith Yamasani                Log.e(TAG, "Unexpected null in startExtractingText : mExtractedText = "
2139a8b00c8801be8e7bd21ddab64a3cde9b5ff2984aAmith Yamasani                        + mExtractedText + ", input connection = " + ic);
2140a8b00c8801be8e7bd21ddab64a3cde9b5ff2984aAmith Yamasani            }
21419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final EditorInfo ei = getCurrentInputEditorInfo();
21429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
21449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                eet.startInternalChanges();
2145105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                onUpdateExtractingVisibility(ei);
2146105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                onUpdateExtractingViews(ei);
21479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int inputType = ei.inputType;
21489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((inputType&EditorInfo.TYPE_MASK_CLASS)
21499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        == EditorInfo.TYPE_CLASS_TEXT) {
21509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if ((inputType&EditorInfo.TYPE_TEXT_FLAG_IME_MULTI_LINE) != 0) {
21519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        inputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
21529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
21539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
21549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                eet.setInputType(inputType);
21559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                eet.setHint(ei.hintText);
21569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mExtractedText != null) {
21579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    eet.setEnabled(true);
21589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    eet.setExtractedText(mExtractedText);
21599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
21609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    eet.setEnabled(false);
21619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    eet.setText("");
21629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
21639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } finally {
21649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                eet.finishInternalChanges();
21659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
21669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (inputChanged) {
21689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                onExtractingInputChanged(ei);
21699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
21709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2172ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok
2173ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    // TODO: Handle the subtype change event
2174ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    /**
2175ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok     * Called when the subtype was changed.
2176ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok     * @param newSubtype the subtype which is being changed to.
2177ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok     */
2178ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    protected void onCurrentInputMethodSubtypeChanged(InputMethodSubtype newSubtype) {
2179ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok        if (DEBUG) {
2180ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok            int nameResId = newSubtype.getNameResId();
21819ef0283bdcd9534cc09ae37eb2b78771b95247b5satok            String mode = newSubtype.getMode();
2182ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok            String output = "changeInputMethodSubtype:"
2183ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok                + (nameResId == 0 ? "<none>" : getString(nameResId)) + ","
21849ef0283bdcd9534cc09ae37eb2b78771b95247b5satok                + mode + ","
2185ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok                + newSubtype.getLocale() + "," + newSubtype.getExtraValue();
2186ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok            Log.v(TAG, "--- " + output);
2187ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok        }
2188ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    }
2189ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok
21909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
21919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Performs a dump of the InputMethodService's internal state.  Override
21929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to add your own information to the dump.
21939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
21949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
21959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Printer p = new PrintWriterPrinter(fout);
21969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("Input method service state for " + this + ":");
21979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mWindowCreated=" + mWindowCreated
2198105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                + " mWindowAdded=" + mWindowAdded);
2199105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        p.println("  mWindowVisible=" + mWindowVisible
2200105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                + " mWindowWasVisible=" + mWindowWasVisible
2201105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                + " mInShowWindow=" + mInShowWindow);
22029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  Configuration=" + getResources().getConfiguration());
22039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mToken=" + mToken);
22049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mInputBinding=" + mInputBinding);
22059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mInputConnection=" + mInputConnection);
22069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mStartedInputConnection=" + mStartedInputConnection);
22079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mInputStarted=" + mInputStarted
22089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mInputViewStarted=" + mInputViewStarted
22099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mCandidatesViewStarted=" + mCandidatesViewStarted);
22109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mInputEditorInfo != null) {
22129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  mInputEditorInfo:");
22139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInputEditorInfo.dump(p, "    ");
22149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
22159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  mInputEditorInfo: null");
22169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mShowInputRequested=" + mShowInputRequested
22199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mLastShowInputRequested=" + mLastShowInputRequested
22209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mShowInputForced=" + mShowInputForced
22219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mShowInputFlags=0x" + Integer.toHexString(mShowInputFlags));
22229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mCandidatesVisibility=" + mCandidatesVisibility
22239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mFullscreenApplied=" + mFullscreenApplied
2224105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                + " mIsFullscreen=" + mIsFullscreen
2225105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                + " mExtractViewHidden=" + mExtractViewHidden);
22269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mExtractedText != null) {
22289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  mExtractedText:");
22299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("    text=" + mExtractedText.text.length() + " chars"
22309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " startOffset=" + mExtractedText.startOffset);
22319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("    selectionStart=" + mExtractedText.selectionStart
22329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " selectionEnd=" + mExtractedText.selectionEnd
22339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " flags=0x" + Integer.toHexString(mExtractedText.flags));
22349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
22359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  mExtractedText: null");
22369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mExtractedToken=" + mExtractedToken);
22389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mIsInputViewShown=" + mIsInputViewShown
22399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mStatusIcon=" + mStatusIcon);
22409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("Last computed insets:");
22419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  contentTopInsets=" + mTmpInsets.contentTopInsets
22429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " visibleTopInsets=" + mTmpInsets.visibleTopInsets
2243fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown                + " touchableInsets=" + mTmpInsets.touchableInsets
2244fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown                + " touchableRegion=" + mTmpInsets.touchableRegion);
22459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2247