InputMethodService.java revision 6e90a362bc66cc67b1beae27b21d3f0148403b08
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,
6216e90a362bc66cc67b1beae27b21d3f0148403b08Adam Powell                android.R.style.Theme_Holo,
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) {
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWindow.dismiss();
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Take care of handling configuration changes.  Subclasses of
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * InputMethodService generally don't need to deal directly with
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this on their own; the standard implementation here takes care of
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * regenerating the input method UI as a result of the configuration
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * change, so you can rely on your {@link #onCreateInputView} and
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * other methods being called as appropriate due to a configuration change.
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>When a configuration change does happen,
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #onInitializeInterface()} is guaranteed to be called the next
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * time prior to any of the other input or UI creation callbacks.  The
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * following will be called immediately depending if appropriate for current
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * state: {@link #onStartInput} if input is active, and
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #onCreateInputView} and {@link #onStartInputView} and related
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * appropriate functions if the UI is displayed.
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override public void onConfigurationChanged(Configuration newConfig) {
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        super.onConfigurationChanged(newConfig);
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean visible = mWindowVisible;
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int showFlags = mShowInputFlags;
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean showingInput = mShowInputRequested;
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CompletionInfo[] completions = mCurCompletions;
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        initViews();
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputViewStarted = false;
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCandidatesViewStarted = false;
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mInputStarted) {
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doStartInput(getCurrentInputConnection(),
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    getCurrentInputEditorInfo(), true);
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (visible) {
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (showingInput) {
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // If we were last showing the soft keyboard, try to do so again.
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (onShowInputRequested(showFlags, true)) {
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    showWindow(true);
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (completions != null) {
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mCurCompletions = completions;
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        onDisplayCompletions(completions);
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    hideWindow();
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (mCandidatesVisibility == View.VISIBLE) {
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // If the candidates are currently visible, make sure the
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // window is shown for them.
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                showWindow(false);
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Otherwise hide the window.
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hideWindow();
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
744865b97761cc58053f45a8b06b531d60d8e482c3asatok            // If user uses hard keyboard, IME button should always be shown.
745857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato            boolean showing = onEvaluateInputViewShown();
746857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato            mImm.setImeWindowStatus(mToken, IME_ACTIVE | (showing ? IME_VISIBLE : 0),
747857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato                    mBackDisposition);
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Implement to return our standard {@link InputMethodImpl}.  Subclasses
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can override to provide their own customized version.
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
755ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    @Override
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AbstractInputMethodImpl onCreateInputMethodInterface() {
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new InputMethodImpl();
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Implement to return our standard {@link InputMethodSessionImpl}.  Subclasses
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can override to provide their own customized version.
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
764ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    @Override
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public AbstractInputMethodSessionImpl onCreateInputMethodSessionInterface() {
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new InputMethodSessionImpl();
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public LayoutInflater getLayoutInflater() {
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInflater;
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public Dialog getWindow() {
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mWindow;
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
777857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    public void setBackDisposition(int disposition) {
778857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato        mBackDisposition = disposition;
779857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    }
780857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato
781857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    public int getBackDisposition() {
782857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato        return mBackDisposition;
783857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato    }
784857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the maximum width, in pixels, available the input method.
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Input methods are positioned at the bottom of the screen and, unless
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * running in fullscreen, will generally want to be as short as possible
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * so should compute their height based on their contents.  However, they
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can stretch as much as needed horizontally.  The function returns to
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * you the maximum amount of space available horizontally, which you can
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * use if needed for UI placement.
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>In many cases this is not needed, you can just rely on the normal
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * view layout mechanisms to position your views within the full horizontal
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * space given to the input method.
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Note that this value can change dynamically, in particular when the
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * screen orientation changes.
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getMaxWidth() {
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return wm.getDefaultDisplay().getWidth();
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return the currently active InputBinding for the input method, or
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * null if there is none.
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public InputBinding getCurrentInputBinding() {
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInputBinding;
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Retrieve the currently active InputConnection that is bound to
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the input method, or null if there is none.
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public InputConnection getCurrentInputConnection() {
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputConnection ic = mStartedInputConnection;
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ic != null) {
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return ic;
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInputConnection;
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean getCurrentInputStarted() {
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInputStarted;
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public EditorInfo getCurrentInputEditorInfo() {
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInputEditorInfo;
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Re-evaluate whether the input method should be running in fullscreen
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * mode, and update its UI if this has changed since the last time it
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * was evaluated.  This will call {@link #onEvaluateFullscreenMode()} to
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * determine whether it should currently run in fullscreen mode.  You
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can use {@link #isFullscreenMode()} to determine if the input method
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is currently running in fullscreen mode.
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void updateFullscreenMode() {
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean isFullscreen = mShowInputRequested && onEvaluateFullscreenMode();
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean changed = mLastShowInputRequested != mShowInputRequested;
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mIsFullscreen != isFullscreen || !mFullscreenApplied) {
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            changed = true;
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIsFullscreen = isFullscreen;
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputConnection ic = getCurrentInputConnection();
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ic != null) ic.reportFullscreenMode(isFullscreen);
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mFullscreenApplied = true;
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            initialize();
852105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)
853105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    mFullscreenArea.getLayoutParams();
854105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            if (isFullscreen) {
855105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                mFullscreenArea.setBackgroundDrawable(mThemeAttrs.getDrawable(
856105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                        com.android.internal.R.styleable.InputMethodService_imeFullscreenBackground));
857105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                lp.height = 0;
858105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                lp.weight = 1;
859105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            } else {
860105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                mFullscreenArea.setBackgroundDrawable(null);
861105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                lp.height = LinearLayout.LayoutParams.WRAP_CONTENT;
862105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                lp.weight = 0;
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
864105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            ((ViewGroup)mFullscreenArea.getParent()).updateViewLayout(
865105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    mFullscreenArea, lp);
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (isFullscreen) {
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mExtractView == null) {
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    View v = onCreateExtractTextView();
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (v != null) {
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        setExtractView(v);
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                startExtractingText(false);
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
875105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            updateExtractFrameVisibility();
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (changed) {
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onConfigureWindow(mWindow.getWindow(), isFullscreen,
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    !mShowInputRequested);
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLastShowInputRequested = mShowInputRequested;
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Update the given window's parameters for the given mode.  This is called
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when the window is first displayed and each time the fullscreen or
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * candidates only mode changes.
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The default implementation makes the layout for the window
891980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * MATCH_PARENT x MATCH_PARENT when in fullscreen mode, and
892980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy     * MATCH_PARENT x WRAP_CONTENT when in non-fullscreen mode.
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param win The input method's window.
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param isFullscreen If true, the window is running in fullscreen mode
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and intended to cover the entire application display.
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param isCandidatesOnly If true, the window is only showing the
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * candidates view and none of the rest of its UI.  This is mutually
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * exclusive with fullscreen mode.
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onConfigureWindow(Window win, boolean isFullscreen,
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean isCandidatesOnly) {
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (isFullscreen) {
904980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy            mWindow.getWindow().setLayout(MATCH_PARENT, MATCH_PARENT);
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
906980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy            mWindow.getWindow().setLayout(MATCH_PARENT, WRAP_CONTENT);
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return whether the input method is <em>currently</em> running in
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * fullscreen mode.  This is the mode that was last determined and
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * applied by {@link #updateFullscreenMode()}.
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isFullscreenMode() {
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mIsFullscreen;
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Override this to control when the input method should run in
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * fullscreen mode.  The default implementation runs in fullsceen only
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when the screen is in landscape mode.  If you change what
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this returns, you will need to call {@link #updateFullscreenMode()}
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * yourself whenever the returned value may have changed to have it
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * re-evaluated and applied.
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onEvaluateFullscreenMode() {
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Configuration config = getResources().getConfiguration();
9292edd68260f26cbd6eddd0df16404bb6bcb22b3b6Leon Scroggins        if (config.orientation != Configuration.ORIENTATION_LANDSCAPE) {
9302edd68260f26cbd6eddd0df16404bb6bcb22b3b6Leon Scroggins            return false;
9312edd68260f26cbd6eddd0df16404bb6bcb22b3b6Leon Scroggins        }
9322edd68260f26cbd6eddd0df16404bb6bcb22b3b6Leon Scroggins        if (mInputEditorInfo != null
9332edd68260f26cbd6eddd0df16404bb6bcb22b3b6Leon Scroggins                && (mInputEditorInfo.imeOptions & EditorInfo.IME_FLAG_NO_FULLSCREEN) != 0) {
9342edd68260f26cbd6eddd0df16404bb6bcb22b3b6Leon Scroggins            return false;
9352edd68260f26cbd6eddd0df16404bb6bcb22b3b6Leon Scroggins        }
9362edd68260f26cbd6eddd0df16404bb6bcb22b3b6Leon Scroggins        return true;
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
940105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * Controls the visibility of the extracted text area.  This only applies
941105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * when the input method is in fullscreen mode, and thus showing extracted
942105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * text.  When false, the extracted text will not be shown, allowing some
943105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * of the application to be seen behind.  This is normally set for you
944105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * by {@link #onUpdateExtractingVisibility}.  This controls the visibility
945105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * of both the extracted text and candidate view; the latter since it is
946105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * not useful if there is no text to see.
947105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     */
948105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    public void setExtractViewShown(boolean shown) {
949105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (mExtractViewHidden == shown) {
950105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mExtractViewHidden = !shown;
951105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            updateExtractFrameVisibility();
952105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
953105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
954105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
955105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    /**
956105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * Return whether the fullscreen extract view is shown.  This will only
957105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * return true if {@link #isFullscreenMode()} returns true, and in that
958105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * case its value depends on the last call to
959105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * {@link #setExtractViewShown(boolean)}.  This effectively lets you
960105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * determine if the application window is entirely covered (when this
961105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * returns true) or if some part of it may be shown (if this returns
962105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * false, though if {@link #isFullscreenMode()} returns true in that case
963105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * then it is probably only a sliver of the application).
964105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     */
965105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    public boolean isExtractViewShown() {
966105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        return mIsFullscreen && !mExtractViewHidden;
967105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
968105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
969105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    void updateExtractFrameVisibility() {
970105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        int vis;
971105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (isFullscreenMode()) {
972105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            vis = mExtractViewHidden ? View.INVISIBLE : View.VISIBLE;
973105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mExtractFrame.setVisibility(View.VISIBLE);
974105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        } else {
975105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            vis = View.VISIBLE;
976105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mExtractFrame.setVisibility(View.GONE);
977105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
978105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        updateCandidatesVisibility(mCandidatesVisibility == View.VISIBLE);
979105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (mWindowWasVisible && mFullscreenArea.getVisibility() != vis) {
980105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            int animRes = mThemeAttrs.getResourceId(vis == View.VISIBLE
981105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    ? com.android.internal.R.styleable.InputMethodService_imeExtractEnterAnimation
982105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    : com.android.internal.R.styleable.InputMethodService_imeExtractExitAnimation,
983105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                    0);
984105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            if (animRes != 0) {
985105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                mFullscreenArea.startAnimation(AnimationUtils.loadAnimation(
986105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                        this, animRes));
987105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            }
988105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
989105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        mFullscreenArea.setVisibility(vis);
990105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
991105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
992105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    /**
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Compute the interesting insets into your UI.  The default implementation
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * uses the top of the candidates frame for the visible insets, and the
9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * top of the input frame for the content insets.  The default touchable
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * insets are {@link Insets#TOUCHABLE_INSETS_VISIBLE}.
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
998105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * <p>Note that this method is not called when
999105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * {@link #isExtractViewShown} returns true, since
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in that case the application is left as-is behind the input method and
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * not impacted by anything in its UI.
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param outInsets Fill in with the current UI insets.
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onComputeInsets(Insets outInsets) {
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int[] loc = mTmpLocation;
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mInputFrame.getVisibility() == View.VISIBLE) {
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInputFrame.getLocationInWindow(loc);
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
1010105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            View decor = getWindow().getWindow().getDecorView();
1011105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            loc[1] = decor.getHeight();
1012105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
1013105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (isFullscreenMode()) {
1014105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            // In fullscreen mode, we never resize the underlying window.
1015105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            View decor = getWindow().getWindow().getDecorView();
1016105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            outInsets.contentTopInsets = decor.getHeight();
1017105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        } else {
1018105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            outInsets.contentTopInsets = loc[1];
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCandidatesFrame.getVisibility() == View.VISIBLE) {
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCandidatesFrame.getLocationInWindow(loc);
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outInsets.visibleTopInsets = loc[1];
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_VISIBLE;
1025fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown        outInsets.touchableRegion.setEmpty();
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Re-evaluate whether the soft input area should currently be shown, and
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * update its UI if this has changed since the last time it
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * was evaluated.  This will call {@link #onEvaluateInputViewShown()} to
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * determine whether the input view should currently be shown.  You
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can use {@link #isInputViewShown()} to determine if the input view
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is currently shown.
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void updateInputViewShown() {
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean isShown = mShowInputRequested && onEvaluateInputViewShown();
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mIsInputViewShown != isShown && mWindowVisible) {
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mIsInputViewShown = isShown;
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInputFrame.setVisibility(isShown ? View.VISIBLE : View.GONE);
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mInputView == null) {
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                initialize();
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                View v = onCreateInputView();
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (v != null) {
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    setInputView(v);
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns true if we have been asked to show our input view.
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isShowInputRequested() {
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mShowInputRequested;
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return whether the soft input view is <em>currently</em> shown to the
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * user.  This is the state that was last determined and
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * applied by {@link #updateInputViewShown()}.
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean isInputViewShown() {
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mIsInputViewShown && mWindowVisible;
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Override this to control when the soft input area should be shown to
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the user.  The default implementation only shows the input view when
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * there is no hard keyboard or the keyboard is hidden.  If you change what
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this returns, you will need to call {@link #updateInputViewShown()}
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * yourself whenever the returned value may have changed to have it
10738cbb4c6e30cff706a243599634aeb8fd9a818d92Gilles Debunne     * re-evaluated and applied.
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onEvaluateInputViewShown() {
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Configuration config = getResources().getConfiguration();
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return config.keyboard == Configuration.KEYBOARD_NOKEYS
10788710e76a897cd546a79ee4338a4147eeb9f3e068Ken Wakasa                || config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES;
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Controls the visibility of the candidates display area.  By default
10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it is hidden.
10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setCandidatesViewShown(boolean shown) {
1086105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        updateCandidatesVisibility(shown);
10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mShowInputRequested && mWindowVisible != shown) {
10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If we are being asked to show the candidates view while the app
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // has not asked for the input view to be shown, then we need
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // to update whether the window is shown.
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (shown) {
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                showWindow(false);
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                hideWindow();
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1099105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    void updateCandidatesVisibility(boolean shown) {
1100105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        int vis = shown ? View.VISIBLE : getCandidatesHiddenVisibility();
1101105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (mCandidatesVisibility != vis) {
1102105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mCandidatesFrame.setVisibility(vis);
1103105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mCandidatesVisibility = vis;
1104105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
1105105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
1106105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the visibility mode (either {@link View#INVISIBLE View.INVISIBLE}
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or {@link View#GONE View.GONE}) of the candidates view when it is not
1110105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * shown.  The default implementation returns GONE when
1111105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * {@link #isExtractViewShown} returns true,
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * otherwise VISIBLE.  Be careful if you change this to return GONE in
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * other situations -- if showing or hiding the candidates view causes
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * your window to resize, this can cause temporary drawing artifacts as
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the resize takes place.
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getCandidatesHiddenVisibility() {
1118105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        return isExtractViewShown() ? View.GONE : View.INVISIBLE;
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showStatusIcon(int iconResId) {
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStatusIcon = iconResId;
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mImm.showStatusIcon(mToken, getPackageName(), iconResId);
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void hideStatusIcon() {
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStatusIcon = 0;
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mImm.hideStatusIcon(mToken);
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Force switch to a new input method, as identified by <var>id</var>.  This
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * input method will be destroyed, and the requested one started on the
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * current input field.
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param id Unique identifier of the new input method ot start.
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void switchInputMethod(String id) {
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mImm.setInputMethod(mToken, id);
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setExtractView(View view) {
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mExtractFrame.removeAllViews();
11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mExtractFrame.addView(view, new FrameLayout.LayoutParams(
1145980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy                ViewGroup.LayoutParams.MATCH_PARENT,
1146980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy                ViewGroup.LayoutParams.MATCH_PARENT));
11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mExtractView = view;
11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (view != null) {
11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractEditText = (ExtractEditText)view.findViewById(
11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    com.android.internal.R.id.inputExtractEditText);
11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractEditText.setIME(this);
11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractAction = (Button)view.findViewById(
11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    com.android.internal.R.id.inputExtractAction);
11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mExtractAction != null) {
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mExtractAccessories = (ViewGroup)view.findViewById(
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        com.android.internal.R.id.inputExtractAccessories);
11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            startExtractingText(false);
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractEditText = null;
11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractAccessories = null;
11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractAction = null;
11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Replaces the current candidates view with a new one.  You only need to
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * call this when dynamically changing the view; normally, you should
11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implement {@link #onCreateCandidatesView()} and create your view when
11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * first needed by the input method.
11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setCandidatesView(View view) {
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCandidatesFrame.removeAllViews();
11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCandidatesFrame.addView(view, new FrameLayout.LayoutParams(
1175980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy                ViewGroup.LayoutParams.MATCH_PARENT,
11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ViewGroup.LayoutParams.WRAP_CONTENT));
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Replaces the current input view with a new one.  You only need to
11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * call this when dynamically changing the view; normally, you should
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implement {@link #onCreateInputView()} and create your view when
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * first needed by the input method.
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setInputView(View view) {
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputFrame.removeAllViews();
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputFrame.addView(view, new FrameLayout.LayoutParams(
1188980a938c1c9a6a5791a8240e5a1e6638ab28dc77Romain Guy                ViewGroup.LayoutParams.MATCH_PARENT,
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ViewGroup.LayoutParams.WRAP_CONTENT));
11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputView = view;
11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called by the framework to create the layout for showing extacted text.
11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Only called when in fullscreen mode.  The returned view hierarchy must
11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * have an {@link ExtractEditText} whose ID is
11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.R.id#inputExtractEditText}.
11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View onCreateExtractTextView() {
12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mInflater.inflate(
12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                com.android.internal.R.layout.input_method_extract_view, null);
12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create and return the view hierarchy used to show candidates.  This will
12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be called once, when the candidates are first displayed.  You can return
12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * null to have no candidates view; the default implementation returns null.
12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>To control when the candidates view is displayed, use
12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #setCandidatesViewShown(boolean)}.
12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * To change the candidates view after the first one is created by this
12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * function, use {@link #setCandidatesView(View)}.
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View onCreateCandidatesView() {
12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Create and return the view hierarchy used for the input area (such as
12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a soft keyboard).  This will be called once, when the input area is
12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * first displayed.  You can return null to have no input area; the default
12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implementation returns null.
12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>To control when the input view is displayed, implement
12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #onEvaluateInputViewShown()}.
12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * To change the input view after the first one is created by this
12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * function, use {@link #setInputView(View)}.
12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public View onCreateInputView() {
12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the input view is being shown and input has started on
12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a new editor.  This will always be called after {@link #onStartInput},
12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * allowing you to do your general setup there and just view-specific
12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * setup here.  You are guaranteed that {@link #onCreateInputView()} will
12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * have been called some time before this function is called.
12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param info Description of the type of text being edited.
12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param restarting Set to true if we are restarting input on the
12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * same text field as before.
12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onStartInputView(EditorInfo info, boolean restarting) {
12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the input view is being hidden from the user.  This will
12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be called either prior to hiding the window, or prior to switching to
12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * another target for editing.
12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The default
12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implementation uses the InputConnection to clear any active composing
12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * text; you can override this (not calling the base class implementation)
12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to perform whatever behavior you would like.
12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12574df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * @param finishingInput If true, {@link #onFinishInput} will be
12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * called immediately after.
12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onFinishInputView(boolean finishingInput) {
12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!finishingInput) {
12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputConnection ic = getCurrentInputConnection();
12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ic != null) {
12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ic.finishComposingText();
12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when only the candidates view has been shown for showing
12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * processing as the user enters text through a hard keyboard.
12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This will always be called after {@link #onStartInput},
12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * allowing you to do your general setup there and just view-specific
12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * setup here.  You are guaranteed that {@link #onCreateCandidatesView()}
12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will have been called some time before this function is called.
12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Note that this will <em>not</em> be called when the input method
12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is running in full editing mode, and thus receiving
12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #onStartInputView} to initiate that operation.  This is only
12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for the case when candidates are being shown while the input method
12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * editor is hidden but wants to show its candidates UI as text is
12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * entered through some other mechanism.
12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param info Description of the type of text being edited.
12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param restarting Set to true if we are restarting input on the
12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * same text field as before.
12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onStartCandidatesView(EditorInfo info, boolean restarting) {
12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the candidates view is being hidden from the user.  This will
12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be called either prior to hiding the window, or prior to switching to
12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * another target for editing.
12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The default
12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implementation uses the InputConnection to clear any active composing
12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * text; you can override this (not calling the base class implementation)
12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to perform whatever behavior you would like.
13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
13014df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * @param finishingInput If true, {@link #onFinishInput} will be
13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * called immediately after.
13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onFinishCandidatesView(boolean finishingInput) {
13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!finishingInput) {
13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputConnection ic = getCurrentInputConnection();
13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ic != null) {
13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ic.finishComposingText();
13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The system has decided that it may be time to show your input method.
13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is called due to a corresponding call to your
13164df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * {@link InputMethod#showSoftInput InputMethod.showSoftInput()}
13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * method.  The default implementation uses
13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #onEvaluateInputViewShown()}, {@link #onEvaluateFullscreenMode()},
13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and the current configuration to decide whether the input view should
13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be shown at this point.
13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param flags Provides additional information about the show request,
13234df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * as per {@link InputMethod#showSoftInput InputMethod.showSoftInput()}.
13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param configChange This is true if we are re-showing due to a
13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * configuration change.
13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns true to indicate that the window should be shown.
13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onShowInputRequested(int flags, boolean configChange) {
13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!onEvaluateInputViewShown()) {
13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((flags&InputMethod.SHOW_EXPLICIT) == 0) {
13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!configChange && onEvaluateFullscreenMode()) {
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Don't show if this is not explicitly requested by the user and
13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // the input method is fullscreen.  That would be too disruptive.
13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // However, we skip this change for a config change, since if
13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // the IME is already shown we do want to go into fullscreen
13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // mode at this point.
13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return false;
13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Configuration config = getResources().getConfiguration();
13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (config.keyboard != Configuration.KEYBOARD_NOKEYS) {
13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // And if the device has a hard keyboard, even if it is
13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // currently hidden, don't show the input method implicitly.
13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // These kinds of devices don't need it that much.
13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return false;
13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((flags&InputMethod.SHOW_FORCED) != 0) {
13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mShowInputForced = true;
13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showWindow(boolean showInput) {
13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DEBUG) Log.v(TAG, "Showing window: showInput=" + showInput
13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mShowInputRequested=" + mShowInputRequested
13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mWindowAdded=" + mWindowAdded
13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mWindowCreated=" + mWindowCreated
13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mWindowVisible=" + mWindowVisible
13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mInputStarted=" + mInputStarted);
1362105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
1363105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (mInShowWindow) {
1364105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            Log.w(TAG, "Re-entrance in to showWindow");
1365105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            return;
1366105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
1367105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
1368105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        try {
1369105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mWindowWasVisible = mWindowVisible;
1370105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mInShowWindow = true;
1371105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            showWindowInner(showInput);
1372105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        } finally {
1373105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mWindowWasVisible = true;
1374105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mInShowWindow = false;
1375105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
1376105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
137706487a58be22b100daf3f950b9a1d25c3ea42aa2satok
1378105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    void showWindowInner(boolean showInput) {
13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean doShowInput = false;
13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean wasVisible = mWindowVisible;
13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mWindowVisible = true;
13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mShowInputRequested) {
13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mInputStarted) {
13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (showInput) {
13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    doShowInput = true;
13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mShowInputRequested = true;
13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            showInput = true;
13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
139206487a58be22b100daf3f950b9a1d25c3ea42aa2satok
13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DEBUG) Log.v(TAG, "showWindow: updating UI");
13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        initialize();
13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updateFullscreenMode();
13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updateInputViewShown();
13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mWindowAdded || !mWindowCreated) {
13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWindowAdded = true;
14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWindowCreated = true;
14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            initialize();
14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "CALL: onCreateCandidatesView");
14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            View v = onCreateCandidatesView();
14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "showWindow: candidates=" + v);
14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (v != null) {
14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setCandidatesView(v);
14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mShowInputRequested) {
14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mInputViewStarted) {
14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (DEBUG) Log.v(TAG, "CALL: onStartInputView");
14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mInputViewStarted = true;
14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                onStartInputView(mInputEditorInfo, false);
14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!mCandidatesViewStarted) {
14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "CALL: onStartCandidatesView");
14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCandidatesViewStarted = true;
14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onStartCandidatesView(mInputEditorInfo, false);
14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (doShowInput) {
14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            startExtractingText(false);
14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
142406487a58be22b100daf3f950b9a1d25c3ea42aa2satok
14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!wasVisible) {
14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "showWindow: showing!");
1427857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato            mImm.setImeWindowStatus(mToken, IME_ACTIVE, mBackDisposition);
14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onWindowShown();
14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWindow.show();
14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
143206487a58be22b100daf3f950b9a1d25c3ea42aa2satok
14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void hideWindow() {
14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mInputViewStarted) {
14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "CALL: onFinishInputView");
14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onFinishInputView(false);
14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (mCandidatesViewStarted) {
14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "CALL: onFinishCandidatesView");
14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onFinishCandidatesView(false);
14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputViewStarted = false;
14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCandidatesViewStarted = false;
1443857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato        mImm.setImeWindowStatus(mToken, 0, mBackDisposition);
14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mWindowVisible) {
14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWindow.hide();
14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mWindowVisible = false;
14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onWindowHidden();
1448105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mWindowWasVisible = false;
14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
145106487a58be22b100daf3f950b9a1d25c3ea42aa2satok
14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the input method window has been shown to the user, after
14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * previously not being visible.  This is done after all of the UI setup
14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * for the window has occurred (creating its views etc).
14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onWindowShown() {
14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the input method window has been hidden from the user,
14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * after previously being visible.
14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onWindowHidden() {
14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when a new client has bound to the input method.  This
14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * may be followed by a series of {@link #onStartInput(EditorInfo, boolean)}
14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and {@link #onFinishInput()} calls as the user navigates through its
14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * UI.  Upon this call you know that {@link #getCurrentInputBinding}
14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and {@link #getCurrentInputConnection} return valid objects.
14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onBindInput() {
14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the previous bound client is no longer associated
14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * with the input method.  After returning {@link #getCurrentInputBinding}
14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and {@link #getCurrentInputConnection} will no longer return
14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * valid objects.
14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onUnbindInput() {
14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called to inform the input method that text input has started in an
14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * editor.  You should use this callback to initialize the state of your
14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * input to match the state of the editor given to it.
14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param attribute The attributes of the editor that input is starting
14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in.
14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param restarting Set to true if input is restarting in the same
14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * editor such as because the application has changed the text in
14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the editor.  Otherwise will be false, indicating this is a new
14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * session with the editor.
14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onStartInput(EditorInfo attribute, boolean restarting) {
14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void doFinishInput() {
15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mInputViewStarted) {
15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "CALL: onFinishInputView");
15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onFinishInputView(true);
15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (mCandidatesViewStarted) {
15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "CALL: onFinishCandidatesView");
15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onFinishCandidatesView(true);
15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputViewStarted = false;
15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCandidatesViewStarted = false;
15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mInputStarted) {
15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DEBUG) Log.v(TAG, "CALL: onFinishInput");
15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onFinishInput();
15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputStarted = false;
15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStartedInputConnection = null;
15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCurCompletions = null;
15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15194df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project
15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void doStartInput(InputConnection ic, EditorInfo attribute, boolean restarting) {
15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!restarting) {
15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            doFinishInput();
15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputStarted = true;
15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStartedInputConnection = ic;
15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputEditorInfo = attribute;
15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        initialize();
15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DEBUG) Log.v(TAG, "CALL: onStartInput");
15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        onStartInput(attribute, restarting);
15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mWindowVisible) {
15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mShowInputRequested) {
15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (DEBUG) Log.v(TAG, "CALL: onStartInputView");
15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mInputViewStarted = true;
15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                onStartInputView(mInputEditorInfo, restarting);
15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                startExtractingText(true);
15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (mCandidatesVisibility == View.VISIBLE) {
15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (DEBUG) Log.v(TAG, "CALL: onStartCandidatesView");
15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mCandidatesViewStarted = true;
15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                onStartCandidatesView(mInputEditorInfo, restarting);
15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called to inform the input method that text input has finished in
15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the last editor.  At this point there may be a call to
15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link #onStartInput(EditorInfo, boolean)} to perform input in a
15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * new editor, or the input method may be left idle.  This method is
15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <em>not</em> called when input restarts in the same editor.
15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The default
15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implementation uses the InputConnection to clear any active composing
15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * text; you can override this (not calling the base class implementation)
15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to perform whatever behavior you would like.
15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onFinishInput() {
15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputConnection ic = getCurrentInputConnection();
15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ic != null) {
15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ic.finishComposingText();
15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the application has reported auto-completion candidates that
15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it would like to have the input method displayed.  Typically these are
15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * only used when an input method is running in full-screen mode, since
15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * otherwise the user can see and interact with the pop-up window of
15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * completions shown by the application.
15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The default implementation here does nothing.
15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onDisplayCompletions(CompletionInfo[] completions) {
15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the application has reported new extracted text to be shown
15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * due to changes in its current text state.  The default implementation
15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * here places the new text in the extract edit text, when the input
15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * method is running in fullscreen mode.
15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onUpdateExtractedText(int token, ExtractedText text) {
15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mExtractedToken != token) {
15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1585b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project        if (text != null) {
1586b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project            if (mExtractEditText != null) {
1587b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project                mExtractedText = text;
1588b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project                mExtractEditText.setExtractedText(text);
1589b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project            }
15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the application has reported a new selection region of
15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the text.  This is called whether or not the input method has requested
15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * extracted text updates, although if so it will not receive this call
15979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if the extracted text has changed as well.
15989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The default implementation takes care of updating the cursor in
16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the extract text, if it is being shown.
16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onUpdateSelection(int oldSelStart, int oldSelEnd,
16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int newSelStart, int newSelEnd,
16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int candidatesStart, int candidatesEnd) {
16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ExtractEditText eet = mExtractEditText;
1606c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project        if (eet != null && isFullscreenMode() && mExtractedText != null) {
16079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int off = mExtractedText.startOffset;
16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            eet.startInternalChanges();
1609c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            newSelStart -= off;
1610c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            newSelEnd -= off;
1611c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            final int len = eet.getText().length();
1612c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            if (newSelStart < 0) newSelStart = 0;
1613c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            else if (newSelStart > len) newSelStart = len;
1614c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            if (newSelEnd < 0) newSelEnd = 0;
1615c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            else if (newSelEnd > len) newSelEnd = len;
1616c39a6e0c51e182338deb8b63d07933b585134929The Android Open Source Project            eet.setSelection(newSelStart, newSelEnd);
16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            eet.finishInternalChanges();
16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1622863fcd62171e55bc9f2105d9fb5877df982454d8satok     * Called when the user tapped or clicked a text view.
1623863fcd62171e55bc9f2105d9fb5877df982454d8satok     * IMEs can't rely on this method being called because this was not part of the original IME
1624863fcd62171e55bc9f2105d9fb5877df982454d8satok     * protocol, so applications with custom text editing written before this method appeared will
1625863fcd62171e55bc9f2105d9fb5877df982454d8satok     * not call to inform the IME of this interaction.
1626863fcd62171e55bc9f2105d9fb5877df982454d8satok     * @param focusChanged true if the user changed the focused view by this click.
1627863fcd62171e55bc9f2105d9fb5877df982454d8satok     */
1628863fcd62171e55bc9f2105d9fb5877df982454d8satok    public void onViewClicked(boolean focusChanged) {
1629863fcd62171e55bc9f2105d9fb5877df982454d8satok    }
1630863fcd62171e55bc9f2105d9fb5877df982454d8satok
1631863fcd62171e55bc9f2105d9fb5877df982454d8satok    /**
16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Called when the application has reported a new location of its text
16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * cursor.  This is only called if explicitly requested by the input method.
16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The default implementation does nothing.
16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onUpdateCursor(Rect newCursor) {
16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Close this input method's soft input area, removing it from the display.
16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The input method will continue running, but the user can no longer use
16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it to generate input by touching the screen.
16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param flags Provides additional operating flags.  Currently may be
16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * 0 or have the {@link InputMethodManager#HIDE_IMPLICIT_ONLY
16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * InputMethodManager.HIDE_IMPLICIT_ONLY} bit set.
16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
16474df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    public void requestHideSelf(int flags) {
16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mImm.hideSoftInputFromInputMethod(mToken, flags);
16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
16524df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * Show the input method. This is a call back to the
16534df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * IMF to handle showing the input method.
16544df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * Close this input method's soft input area, removing it from the display.
16554df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * The input method will continue running, but the user can no longer use
16564df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * it to generate input by touching the screen.
16574df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * @param flags Provides additional operating flags.  Currently may be
16584df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * 0 or have the {@link InputMethodManager#SHOW_FORCED
16594df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * InputMethodManager.} bit set.
16604df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     */
16614df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    private void requestShowSelf(int flags) {
16624df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        mImm.showSoftInputFromInputMethod(mToken, flags);
16634df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    }
16644df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project
166583fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn    private boolean handleBack(boolean doIt) {
166683fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        if (mShowInputRequested) {
166783fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            // If the soft input area is shown, back closes it and we
166883fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            // consume the back key.
166983fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            if (doIt) requestHideSelf(0);
167083fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            return true;
167183fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        } else if (mWindowVisible) {
167283fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            if (mCandidatesVisibility == View.VISIBLE) {
167383fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                // If we are showing candidates even if no input area, then
167483fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                // hide them.
167583fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                if (doIt) setCandidatesViewShown(false);
167683fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            } else {
167783fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                // If we have the window visible for some other reason --
167883fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                // most likely to show candidates -- then just get rid
167983fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                // of it.  This really shouldn't happen, but just in case...
168083fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                if (doIt) hideWindow();
168183fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            }
168283fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            return true;
168383fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        }
168483fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        return false;
168583fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn    }
168683fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn
16874df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    /**
16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Override this to intercept key down events before they are processed by the
16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * application.  If you return true, the application will not itself
16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * process the event.  If you return true, the normal application processing
16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will occur as if the IME had not seen the event at all.
16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The default implementation intercepts {@link KeyEvent#KEYCODE_BACK
169483fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * KeyEvent.KEYCODE_BACK} if the IME is currently shown, to
169583fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * possibly hide it when the key goes up (if not canceled or long pressed).  In
169683fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * addition, in fullscreen mode only, it will consume DPAD movement
16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * events to move the cursor in the extracted text view, not allowing
16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * them to perform navigation in the underlying application.
16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onKeyDown(int keyCode, KeyEvent event) {
170183fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
170283fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            if (handleBack(false)) {
170383fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                event.startTracking();
17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
170683fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            return false;
17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return doMovementKey(keyCode, event, MOVEMENT_DOWN);
17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
171283fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * Default implementation of {@link KeyEvent.Callback#onKeyLongPress(int, KeyEvent)
171383fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle
171483fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * the event).
171583fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     */
171683fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn    public boolean onKeyLongPress(int keyCode, KeyEvent event) {
171783fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        return false;
171883fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn    }
171983fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn
172083fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn    /**
17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Override this to intercept special key multiple events before they are
17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * processed by the
17239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * application.  If you return true, the application will not itself
17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * process the event.  If you return true, the normal application processing
17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will occur as if the IME had not seen the event at all.
17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The default implementation always returns false, except when
17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in fullscreen mode, where it will consume DPAD movement
17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * events to move the cursor in the extracted text view, not allowing
17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * them to perform navigation in the underlying application.
17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onKeyMultiple(int keyCode, int count, KeyEvent event) {
17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return doMovementKey(keyCode, event, count);
17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Override this to intercept key up events before they are processed by the
17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * application.  If you return true, the application will not itself
17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * process the event.  If you return true, the normal application processing
17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will occur as if the IME had not seen the event at all.
17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
174283fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * <p>The default implementation intercepts {@link KeyEvent#KEYCODE_BACK
174383fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * KeyEvent.KEYCODE_BACK} to hide the current IME UI if it is shown.  In
174483fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn     * addition, in fullscreen mode only, it will consume DPAD movement
17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * events to move the cursor in the extracted text view, not allowing
17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * them to perform navigation in the underlying application.
17479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
17489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onKeyUp(int keyCode, KeyEvent event) {
174983fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.isTracking()
175083fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn                && !event.isCanceled()) {
175183fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn            return handleBack(true);
175283fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn        }
175383fe3f559249451706957b1a5f660b2b8272f114Dianne Hackborn
17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return doMovementKey(keyCode, event, MOVEMENT_UP);
17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1757ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    @Override
17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onTrackballEvent(MotionEvent event) {
17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onAppPrivateCommand(String action, Bundle data) {
17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17654df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    /**
17664df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     * Handle a request by the system to toggle the soft input area.
17674df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project     */
17684df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    private void onToggleSoftInput(int showFlags, int hideFlags) {
17694df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        if (DEBUG) Log.v(TAG, "toggleSoftInput()");
17704df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        if (isInputViewShown()) {
17714df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            requestHideSelf(hideFlags);
17724df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        } else {
17734df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            requestShowSelf(showFlags);
17744df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        }
17754df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    }
17764df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project
17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MOVEMENT_DOWN = -1;
17789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MOVEMENT_UP = -2;
17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void reportExtractedMovement(int keyCode, int count) {
17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int dx = 0, dy = 0;
17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (keyCode) {
17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case KeyEvent.KEYCODE_DPAD_LEFT:
17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dx = -count;
17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case KeyEvent.KEYCODE_DPAD_RIGHT:
17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dx = count;
17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case KeyEvent.KEYCODE_DPAD_UP:
17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dy = -count;
17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case KeyEvent.KEYCODE_DPAD_DOWN:
17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                dy = count;
17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1796ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok        onExtractedCursorMovement(dx, dy);
17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean doMovementKey(int keyCode, KeyEvent event, int count) {
18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ExtractEditText eet = mExtractEditText;
1801105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (isExtractViewShown() && isInputViewShown() && eet != null) {
18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If we are in fullscreen mode, the cursor will move around
18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // the extract edit text, but should NOT cause focus to move
18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // to other fields.
18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            MovementMethod movement = eet.getMovementMethod();
18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Layout layout = eet.getLayout();
18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (movement != null && layout != null) {
18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // We want our own movement method to handle the key, so the
18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // cursor will properly move in our own word wrapping.
18109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (count == MOVEMENT_DOWN) {
18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (movement.onKeyDown(eet,
18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            (Spannable)eet.getText(), keyCode, event)) {
18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        reportExtractedMovement(keyCode, 1);
18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return true;
18159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (count == MOVEMENT_UP) {
18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (movement.onKeyUp(eet,
18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            (Spannable)eet.getText(), keyCode, event)) {
18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return true;
18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (movement.onKeyOther(eet, (Spannable)eet.getText(), event)) {
18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        reportExtractedMovement(keyCode, count);
18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
1825105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                        KeyEvent down = KeyEvent.changeAction(event, KeyEvent.ACTION_DOWN);
18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (movement.onKeyDown(eet,
18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                (Spannable)eet.getText(), keyCode, down)) {
1828105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                            KeyEvent up = KeyEvent.changeAction(event, KeyEvent.ACTION_UP);
18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            movement.onKeyUp(eet,
18309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    (Spannable)eet.getText(), keyCode, up);
18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            while (--count > 0) {
18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                movement.onKeyDown(eet,
18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        (Spannable)eet.getText(), keyCode, down);
18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                movement.onKeyUp(eet,
18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        (Spannable)eet.getText(), keyCode, up);
18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
18379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            reportExtractedMovement(keyCode, count);
18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Regardless of whether the movement method handled the key,
18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // we never allow DPAD navigation to the application.
18449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (keyCode) {
18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case KeyEvent.KEYCODE_DPAD_LEFT:
18469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case KeyEvent.KEYCODE_DPAD_RIGHT:
18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case KeyEvent.KEYCODE_DPAD_UP:
18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                case KeyEvent.KEYCODE_DPAD_DOWN:
18499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return true;
18509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
18549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Send the given key event code (as defined by {@link KeyEvent}) to the
18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * current input connection is a key down + key up event pair.  The sent
18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * events have {@link KeyEvent#FLAG_SOFT_KEYBOARD KeyEvent.FLAG_SOFT_KEYBOARD}
18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * set, so that the recipient can identify them as coming from a software
18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * input method, and
18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link KeyEvent#FLAG_KEEP_TOUCH_MODE KeyEvent.FLAG_KEEP_TOUCH_MODE}, so
18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * that they don't impact the current touch mode of the UI.
18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param keyEventCode The raw key code to send, as defined by
18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link KeyEvent}.
18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void sendDownUpKeyEvents(int keyEventCode) {
18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputConnection ic = getCurrentInputConnection();
18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ic == null) return;
18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long eventTime = SystemClock.uptimeMillis();
18729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ic.sendKeyEvent(new KeyEvent(eventTime, eventTime,
18736b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                KeyEvent.ACTION_DOWN, keyEventCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));
18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ic.sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime,
18766b53e8daa69cba1a2a5a7c95a01e37ce9c53226cJeff Brown                KeyEvent.ACTION_UP, keyEventCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));
18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Ask the input target to execute its default action via
18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link InputConnection#performEditorAction
18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * InputConnection.performEditorAction()}.
18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param fromEnterKey If true, this will be executed as if the user had
18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * pressed an enter key on the keyboard, that is it will <em>not</em>
18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * be done if the editor has set {@link EditorInfo#IME_FLAG_NO_ENTER_ACTION
18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * EditorInfo.IME_FLAG_NO_ENTER_ACTION}.  If false, the action will be
18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * sent regardless of how the editor has set that flag.
18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a boolean indicating whether an action has been sent.
18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If false, either the editor did not specify a default action or it
18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * does not want an action from the enter key.  If true, the action was
18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * sent (or there was no input connection at all).
18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean sendDefaultEditorAction(boolean fromEnterKey) {
18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        EditorInfo ei = getCurrentInputEditorInfo();
18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ei != null &&
18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (!fromEnterKey || (ei.imeOptions &
19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        EditorInfo.IME_FLAG_NO_ENTER_ACTION) == 0) &&
19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (ei.imeOptions & EditorInfo.IME_MASK_ACTION) !=
19029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    EditorInfo.IME_ACTION_NONE) {
19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If the enter key was pressed, and the editor has a default
19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // action associated with pressing enter, then send it that
19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // explicit action instead of the key event.
19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputConnection ic = getCurrentInputConnection();
19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ic != null) {
19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ic.performEditorAction(ei.imeOptions&EditorInfo.IME_MASK_ACTION);
19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return true;
19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Send the given UTF-16 character to the current input connection.  Most
19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * characters will be delivered simply by calling
19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link InputConnection#commitText InputConnection.commitText()} with
19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the character; some, however, may be handled different.  In particular,
19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the enter character ('\n') will either be delivered as an action code
19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or a raw key event, as appropriate.
19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
19249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param charCode The UTF-16 character code to send.
19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void sendKeyChar(char charCode) {
19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (charCode) {
19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case '\n': // Apps may be listening to an enter key to perform an action
19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (!sendDefaultEditorAction(true)) {
19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sendDownUpKeyEvents(KeyEvent.KEYCODE_ENTER);
19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            default:
19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Make sure that digits go through any text watcher on the client side.
19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (charCode >= '0' && charCode <= '9') {
19369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sendDownUpKeyEvents(charCode - '0' + KeyEvent.KEYCODE_0);
19379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    InputConnection ic = getCurrentInputConnection();
19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (ic != null) {
19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ic.commitText(String.valueOf((char) charCode), 1);
19419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is called when the user has moved the cursor in the extracted
19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * text view, when running in fullsreen mode.  The default implementation
19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * performs the corresponding selection change on the underlying text
19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * editor.
19529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onExtractedSelectionChanged(int start, int end) {
19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputConnection conn = getCurrentInputConnection();
19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (conn != null) {
19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            conn.setSelection(start, end);
19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is called when the user has clicked on the extracted text view,
19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * when running in fullscreen mode.  The default implementation hides
19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the candidates view when this happens, but only if the extracted text
19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * editor has a vertical scroll bar because its text doesn't fit.
19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Re-implement this to provide whatever behavior you want.
19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onExtractedTextClicked() {
19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mExtractEditText == null) {
19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mExtractEditText.hasVerticalScrollBar()) {
19729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setCandidatesViewShown(false);
19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is called when the user has performed a cursor movement in the
19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * extracted text view, when it is running in fullscreen mode.  The default
19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implementation hides the candidates view when a vertical movement
19809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * happens, but only if the extracted text editor has a vertical scroll bar
19819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * because its text doesn't fit.
19829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Re-implement this to provide whatever behavior you want.
19839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param dx The amount of cursor movement in the x dimension.
19849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param dy The amount of cursor movement in the y dimension.
19859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
19869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onExtractedCursorMovement(int dx, int dy) {
19879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mExtractEditText == null || dy == 0) {
19889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
19899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mExtractEditText.hasVerticalScrollBar()) {
19919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            setCandidatesViewShown(false);
19929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
19969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is called when the user has selected a context menu item from the
19979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * extracted text view, when running in fullscreen mode.  The default
19989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * implementation sends this action to the current InputConnection's
19999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link InputConnection#performContextMenuAction(int)}, for it
20009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to be processed in underlying "real" editor.  Re-implement this to
20019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * provide whatever behavior you want.
20029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
20039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onExtractTextContextMenuItem(int id) {
20049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputConnection ic = getCurrentInputConnection();
20059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ic != null) {
20069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ic.performContextMenuAction(id);
20079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
20099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
20129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Return text that can be used as a button label for the given
20139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link EditorInfo#imeOptions EditorInfo.imeOptions}.  Returns null
20149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if there is no action requested.  Note that there is no guarantee that
20159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the returned text will be relatively short, so you probably do not
20169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * want to use it as text on a soft keyboard key label.
20179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
20189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param imeOptions The value from @link EditorInfo#imeOptions EditorInfo.imeOptions}.
20199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
20209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns a label to use, or null if there is no action.
20219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
20229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public CharSequence getTextForImeAction(int imeOptions) {
20239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (imeOptions&EditorInfo.IME_MASK_ACTION) {
20249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EditorInfo.IME_ACTION_NONE:
20259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return null;
20269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EditorInfo.IME_ACTION_GO:
20279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getText(com.android.internal.R.string.ime_action_go);
20289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EditorInfo.IME_ACTION_SEARCH:
20299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getText(com.android.internal.R.string.ime_action_search);
20309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EditorInfo.IME_ACTION_SEND:
20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getText(com.android.internal.R.string.ime_action_send);
20329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case EditorInfo.IME_ACTION_NEXT:
20339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getText(com.android.internal.R.string.ime_action_next);
20344df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            case EditorInfo.IME_ACTION_DONE:
20354df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                return getText(com.android.internal.R.string.ime_action_done);
2036dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn            case EditorInfo.IME_ACTION_PREVIOUS:
2037dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn                return getText(com.android.internal.R.string.ime_action_previous);
20389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            default:
20399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return getText(com.android.internal.R.string.ime_action_default);
20409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
20429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2044105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * Called when the fullscreen-mode extracting editor info has changed,
2045105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * to determine whether the extracting (extract text and candidates) portion
2046105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * of the UI should be shown.  The standard implementation hides or shows
2047105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * the extract area depending on whether it makes sense for the
2048105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * current editor.  In particular, a {@link InputType#TYPE_NULL}
2049105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * input type or {@link EditorInfo#IME_FLAG_NO_EXTRACT_UI} flag will
2050105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * turn off the extract area since there is no text to be shown.
2051105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     */
2052105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    public void onUpdateExtractingVisibility(EditorInfo ei) {
2053105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (ei.inputType == InputType.TYPE_NULL ||
2054105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                (ei.imeOptions&EditorInfo.IME_FLAG_NO_EXTRACT_UI) != 0) {
2055105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            // No reason to show extract UI!
2056105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            setExtractViewShown(false);
2057105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            return;
2058105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
2059105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
2060105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        setExtractViewShown(true);
2061105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
2062105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
2063105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    /**
2064105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * Called when the fullscreen-mode extracting editor info has changed,
2065105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * to update the state of its UI such as the action buttons shown.
2066105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * You do not need to deal with this if you are using the standard
20679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * full screen extract UI.  If replacing it, you will need to re-implement
2068105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * this to put the appropriate action button in your own UI and handle it,
2069105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * and perform any other changes.
2070105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     *
2071105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * <p>The standard implementation turns on or off its accessory area
2072105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * depending on whether there is an action button, and hides or shows
2073105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * the entire extract area depending on whether it makes sense for the
2074105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * current editor.  In particular, a {@link InputType#TYPE_NULL} or
2075105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * {@link InputType#TYPE_TEXT_VARIATION_FILTER} input type will turn off the
2076105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project     * extract area since there is no text to be shown.
20779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2078105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    public void onUpdateExtractingViews(EditorInfo ei) {
2079105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (!isExtractViewShown()) {
2080105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            return;
2081105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
2082105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project
20839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mExtractAccessories == null) {
20849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
20859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
20869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final boolean hasAction = ei.actionLabel != null || (
20879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                (ei.imeOptions&EditorInfo.IME_MASK_ACTION) != EditorInfo.IME_ACTION_NONE &&
2088105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                (ei.imeOptions&EditorInfo.IME_FLAG_NO_ACCESSORY_ACTION) == 0 &&
2089105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                ei.inputType != InputType.TYPE_NULL);
20909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (hasAction) {
20919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractAccessories.setVisibility(View.VISIBLE);
209259eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik            if (mExtractAction != null) {
209359eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik                if (ei.actionLabel != null) {
209459eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik                    mExtractAction.setText(ei.actionLabel);
209559eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik                } else {
209659eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik                    mExtractAction.setText(getTextForImeAction(ei.imeOptions));
209759eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik                }
209859eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik                mExtractAction.setOnClickListener(mActionClickListener);
20999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
21009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
21019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractAccessories.setVisibility(View.GONE);
210259eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik            if (mExtractAction != null) {
210359eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik                mExtractAction.setOnClickListener(null);
210459eb69192c47ba53cf2ea412a5fba160f2a7892dSteve Kondik            }
21059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
21099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is called when, while currently displayed in extract mode, the
21109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * current input target changes.  The default implementation will
21119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * auto-hide the IME if the new target is not a full editor, since this
21129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * can be an confusing experience for the user.
21139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
21149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onExtractingInputChanged(EditorInfo ei) {
21159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ei.inputType == InputType.TYPE_NULL) {
21164df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            requestHideSelf(InputMethodManager.HIDE_NOT_ALWAYS);
21179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
21199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void startExtractingText(boolean inputChanged) {
21219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ExtractEditText eet = mExtractEditText;
21229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (eet != null && getCurrentInputStarted()
21239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && isFullscreenMode()) {
21249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mExtractedToken++;
21259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ExtractedTextRequest req = new ExtractedTextRequest();
21269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            req.token = mExtractedToken;
21279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            req.flags = InputConnection.GET_TEXT_WITH_STYLES;
21289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            req.hintMaxLines = 10;
21299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            req.hintMaxChars = 10000;
2130ba4d93fcd76fdd7c8368e23c7faf9a20684e51a0Amith Yamasani            InputConnection ic = getCurrentInputConnection();
2131ba4d93fcd76fdd7c8368e23c7faf9a20684e51a0Amith Yamasani            mExtractedText = ic == null? null
2132ba4d93fcd76fdd7c8368e23c7faf9a20684e51a0Amith Yamasani                    : ic.getExtractedText(req, InputConnection.GET_EXTRACTED_TEXT_MONITOR);
2133a8b00c8801be8e7bd21ddab64a3cde9b5ff2984aAmith Yamasani            if (mExtractedText == null || ic == null) {
2134a8b00c8801be8e7bd21ddab64a3cde9b5ff2984aAmith Yamasani                Log.e(TAG, "Unexpected null in startExtractingText : mExtractedText = "
2135a8b00c8801be8e7bd21ddab64a3cde9b5ff2984aAmith Yamasani                        + mExtractedText + ", input connection = " + ic);
2136a8b00c8801be8e7bd21ddab64a3cde9b5ff2984aAmith Yamasani            }
21379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final EditorInfo ei = getCurrentInputEditorInfo();
21389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
21409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                eet.startInternalChanges();
2141105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                onUpdateExtractingVisibility(ei);
2142105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                onUpdateExtractingViews(ei);
21439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int inputType = ei.inputType;
21449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if ((inputType&EditorInfo.TYPE_MASK_CLASS)
21459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        == EditorInfo.TYPE_CLASS_TEXT) {
21469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if ((inputType&EditorInfo.TYPE_TEXT_FLAG_IME_MULTI_LINE) != 0) {
21479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        inputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
21489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
21499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
21509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                eet.setInputType(inputType);
21519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                eet.setHint(ei.hintText);
21529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mExtractedText != null) {
21539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    eet.setEnabled(true);
21549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    eet.setExtractedText(mExtractedText);
21559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
21569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    eet.setEnabled(false);
21579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    eet.setText("");
21589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
21599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } finally {
21609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                eet.finishInternalChanges();
21619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
21629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
21639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (inputChanged) {
21649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                onExtractingInputChanged(ei);
21659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
21669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
21679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2168ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok
2169ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    // TODO: Handle the subtype change event
2170ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    /**
2171ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok     * Called when the subtype was changed.
2172ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok     * @param newSubtype the subtype which is being changed to.
2173ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok     */
2174ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    protected void onCurrentInputMethodSubtypeChanged(InputMethodSubtype newSubtype) {
2175ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok        if (DEBUG) {
2176ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok            int nameResId = newSubtype.getNameResId();
21779ef0283bdcd9534cc09ae37eb2b78771b95247b5satok            String mode = newSubtype.getMode();
2178ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok            String output = "changeInputMethodSubtype:"
2179ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok                + (nameResId == 0 ? "<none>" : getString(nameResId)) + ","
21809ef0283bdcd9534cc09ae37eb2b78771b95247b5satok                + mode + ","
2181ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok                + newSubtype.getLocale() + "," + newSubtype.getExtraValue();
2182ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok            Log.v(TAG, "--- " + output);
2183ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok        }
2184ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    }
2185ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok
21869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
21879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Performs a dump of the InputMethodService's internal state.  Override
21889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to add your own information to the dump.
21899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
21909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
21919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Printer p = new PrintWriterPrinter(fout);
21929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("Input method service state for " + this + ":");
21939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mWindowCreated=" + mWindowCreated
2194105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                + " mWindowAdded=" + mWindowAdded);
2195105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        p.println("  mWindowVisible=" + mWindowVisible
2196105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                + " mWindowWasVisible=" + mWindowWasVisible
2197105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                + " mInShowWindow=" + mInShowWindow);
21989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  Configuration=" + getResources().getConfiguration());
21999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mToken=" + mToken);
22009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mInputBinding=" + mInputBinding);
22019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mInputConnection=" + mInputConnection);
22029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mStartedInputConnection=" + mStartedInputConnection);
22039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mInputStarted=" + mInputStarted
22049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mInputViewStarted=" + mInputViewStarted
22059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mCandidatesViewStarted=" + mCandidatesViewStarted);
22069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mInputEditorInfo != null) {
22089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  mInputEditorInfo:");
22099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInputEditorInfo.dump(p, "    ");
22109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
22119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  mInputEditorInfo: null");
22129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mShowInputRequested=" + mShowInputRequested
22159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mLastShowInputRequested=" + mLastShowInputRequested
22169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mShowInputForced=" + mShowInputForced
22179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mShowInputFlags=0x" + Integer.toHexString(mShowInputFlags));
22189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mCandidatesVisibility=" + mCandidatesVisibility
22199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mFullscreenApplied=" + mFullscreenApplied
2220105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                + " mIsFullscreen=" + mIsFullscreen
2221105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                + " mExtractViewHidden=" + mExtractViewHidden);
22229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
22239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mExtractedText != null) {
22249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  mExtractedText:");
22259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("    text=" + mExtractedText.text.length() + " chars"
22269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " startOffset=" + mExtractedText.startOffset);
22279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("    selectionStart=" + mExtractedText.selectionStart
22289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " selectionEnd=" + mExtractedText.selectionEnd
22299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " flags=0x" + Integer.toHexString(mExtractedText.flags));
22309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
22319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  mExtractedText: null");
22329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
22339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mExtractedToken=" + mExtractedToken);
22349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  mIsInputViewShown=" + mIsInputViewShown
22359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " mStatusIcon=" + mStatusIcon);
22369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("Last computed insets:");
22379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p.println("  contentTopInsets=" + mTmpInsets.contentTopInsets
22389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                + " visibleTopInsets=" + mTmpInsets.visibleTopInsets
2239fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown                + " touchableInsets=" + mTmpInsets.touchableInsets
2240fbf097732137a32930d151f7ba6816a5b870c32aJeff Brown                + " touchableRegion=" + mTmpInsets.touchableRegion);
22419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
22429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2243