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.view.inputmethod; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganovimport com.android.internal.os.SomeArgs; 208cbb4c6e30cff706a243599634aeb8fd9a818d92Gilles Debunneimport com.android.internal.view.IInputConnectionWrapper; 218cbb4c6e30cff706a243599634aeb8fd9a818d92Gilles Debunneimport com.android.internal.view.IInputContext; 228cbb4c6e30cff706a243599634aeb8fd9a818d92Gilles Debunneimport com.android.internal.view.IInputMethodClient; 238cbb4c6e30cff706a243599634aeb8fd9a818d92Gilles Debunneimport com.android.internal.view.IInputMethodManager; 248cbb4c6e30cff706a243599634aeb8fd9a818d92Gilles Debunneimport com.android.internal.view.IInputMethodSession; 258cbb4c6e30cff706a243599634aeb8fd9a818d92Gilles Debunneimport com.android.internal.view.InputBindResult; 268cbb4c6e30cff706a243599634aeb8fd9a818d92Gilles Debunne 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Rect; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Looper; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 354df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Projectimport android.os.ResultReceiver; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager; 37f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brownimport android.os.Trace; 38f9f01008624e2d28c15a90d942fa36f98c8c967dsatokimport android.text.style.SuggestionSpan; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 40f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brownimport android.util.Pools.Pool; 41f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brownimport android.util.Pools.SimplePool; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.PrintWriterPrinter; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Printer; 44c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownimport android.view.InputChannel; 45c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownimport android.view.InputEvent; 46c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownimport android.view.InputEventSender; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.View; 496dd005b48138708762bfade0081d031a2a4a3822Dianne Hackbornimport android.view.ViewRootImpl; 50f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brownimport android.util.SparseArray; 51d4723bb415dc70008c744d1027c3e3d9473adfe1Gilles Debunne 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter; 544e4569dab5c75804b01a19b2d6e6101b445c1c68satokimport java.util.ArrayList; 55f3db1af8d55ab247b6db67baf4fe772c18f33cabsatokimport java.util.HashMap; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 57f3db1af8d55ab247b6db67baf4fe772c18f33cabsatokimport java.util.Map; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.CountDownLatch; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.TimeUnit; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Central system API to the overall input method framework (IMF) architecture, 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * which arbitrates interaction between applications and the current input method. 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You can retrieve an instance of this interface with 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Context#getSystemService(String) Context.getSystemService()}. 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Topics covered here: 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ol> 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li><a href="#ArchitectureOverview">Architecture Overview</a> 70384f8bad60037855d2a43d7c661ca1b75ccd08baKen Wakasa * <li><a href="#Applications">Applications</a> 71384f8bad60037855d2a43d7c661ca1b75ccd08baKen Wakasa * <li><a href="#InputMethods">Input Methods</a> 72384f8bad60037855d2a43d7c661ca1b75ccd08baKen Wakasa * <li><a href="#Security">Security</a> 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ol> 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <a name="ArchitectureOverview"></a> 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h3>Architecture Overview</h3> 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>There are three primary parties involved in the input method 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * framework (IMF) architecture:</p> 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> The <strong>input method manager</strong> as expressed by this class 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * is the central point of the system that manages interaction between all 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * other parts. It is expressed as the client-side API here which exists 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in each application context and communicates with a global system service 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that manages the interaction across all processes. 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> An <strong>input method (IME)</strong> implements a particular 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * interaction model allowing the user to generate text. The system binds 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to the current input method that is use, causing it to be created and run, 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and tells it when to hide and show its UI. Only one IME is running at a time. 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> Multiple <strong>client applications</strong> arbitrate with the input 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * method manager for input focus and control over the state of the IME. Only 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * one such client is ever active (working with the IME) at a time. 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <a name="Applications"></a> 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h3>Applications</h3> 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>In most cases, applications that are using the standard 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.widget.TextView} or its subclasses will have little they need 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to do to work well with soft input methods. The main things you need to 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be aware of are:</p> 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 1068cbb4c6e30cff706a243599634aeb8fd9a818d92Gilles Debunne * <li> Properly set the {@link android.R.attr#inputType} in your editable 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * text views, so that the input method will have enough context to help the 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * user in entering text into them. 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> Deal well with losing screen space when the input method is 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * displayed. Ideally an application should handle its window being resized 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * smaller, but it can rely on the system performing panning of the window 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if needed. You should set the {@link android.R.attr#windowSoftInputMode} 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * attribute on your activity or the corresponding values on windows you 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * create to help the system determine whether to pan or resize (it will 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * try to determine this automatically but may get it wrong). 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> You can also control the preferred soft input state (open, closed, etc) 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for your window using the same {@link android.R.attr#windowSoftInputMode} 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * attribute. 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>More finer-grained control is available through the APIs here to directly 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * interact with the IMF and its IME -- either showing or hiding the input 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * area, letting the user pick an input method, etc.</p> 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>For the rare people amongst us writing their own text editors, you 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * will need to implement {@link android.view.View#onCreateInputConnection} 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to return a new instance of your own {@link InputConnection} interface 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * allowing the IME to interact with your editor.</p> 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <a name="InputMethods"></a> 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h3>Input Methods</h3> 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>An input method (IME) is implemented 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as a {@link android.app.Service}, typically deriving from 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.inputmethodservice.InputMethodService}. It must provide 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the core {@link InputMethod} interface, though this is normally handled by 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.inputmethodservice.InputMethodService} and implementors will 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * only need to deal with the higher-level API there.</p> 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the {@link android.inputmethodservice.InputMethodService} class for 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * more information on implementing IMEs. 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <a name="Security"></a> 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <h3>Security</h3> 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>There are a lot of security issues associated with input methods, 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * since they essentially have freedom to completely drive the UI and monitor 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * everything the user enters. The Android input method framework also allows 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * arbitrary third party IMEs, so care must be taken to restrict their 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * selection and interactions.</p> 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Here are some key points about the security architecture behind the 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * IMF:</p> 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <ul> 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> <p>Only the system is allowed to directly access an IME's 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link InputMethod} interface, via the 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.Manifest.permission#BIND_INPUT_METHOD} permission. This is 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * enforced in the system by not binding to an input method service that does 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * not require this permission, so the system can guarantee no other untrusted 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * clients are accessing the current input method outside of its control.</p> 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> <p>There may be many client processes of the IMF, but only one may 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be active at a time. The inactive clients can not interact with key 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * parts of the IMF through the mechanisms described below.</p> 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> <p>Clients of an input method are only given access to its 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link InputMethodSession} interface. One instance of this interface is 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * created for each client, and only calls from the session associated with 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the active client will be processed by the current IME. This is enforced 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by {@link android.inputmethodservice.AbstractInputMethodService} for normal 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * IMEs, but must be explicitly handled by an IME that is customizing the 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * raw {@link InputMethodSession} implementation.</p> 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> <p>Only the active client's {@link InputConnection} will accept 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * operations. The IMF tells each client process whether it is active, and 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the framework enforces that in inactive processes calls on to the current 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * InputConnection will be ignored. This ensures that the current IME can 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * only deliver events and text edits to the UI that the user sees as 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * being in focus.</p> 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> <p>An IME can never interact with an {@link InputConnection} while 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the screen is off. This is enforced by making all clients inactive while 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the screen is off, and prevents bad IMEs from driving the UI when the user 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * can not be aware of its behavior.</p> 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> <p>A client application can ask that the system let the user pick a 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * new IME, but can not programmatically switch to one itself. This avoids 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * malicious applications from switching the user to their own IME, which 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * remains running when the user navigates away to another application. An 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * IME, on the other hand, <em>is</em> allowed to programmatically switch 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the system to another IME, since it already has full control of user 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * input.</p> 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <li> <p>The user must explicitly enable a new IME in settings before 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * they can switch to it, to confirm with the system that they know about it 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * and want to make it available for use.</p> 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </ul> 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic final class InputMethodManager { 2034eba271a64b98a5fc38227f40190b879f807acf5Dianne Hackborn static final boolean DEBUG = false; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final String TAG = "InputMethodManager"; 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 206f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown static final String PENDING_EVENT_COUNTER = "aq:imm"; 207f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 208f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown static InputMethodManager sInstance; 2097663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn 2107663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn /** 2117663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn * @hide Flag for IInputMethodManager.windowGainedFocus: a view in 2127663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn * the window has input focus. 2137663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn */ 2147663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn public static final int CONTROL_WINDOW_VIEW_HAS_FOCUS = 1<<0; 2157663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn 2167663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn /** 2177663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn * @hide Flag for IInputMethodManager.windowGainedFocus: the focus 2187663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn * is a text editor. 2197663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn */ 2207663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn public static final int CONTROL_WINDOW_IS_TEXT_EDITOR = 1<<1; 2217663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn 2227663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn /** 2237663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn * @hide Flag for IInputMethodManager.windowGainedFocus: this is the first 2247663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn * time the window has gotten focus. 2257663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn */ 2267663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn public static final int CONTROL_WINDOW_FIRST = 1<<2; 2277663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn 2287663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn /** 2297663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn * @hide Flag for IInputMethodManager.startInput: this is the first 2307663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn * time the window has gotten focus. 2317663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn */ 2327663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn public static final int CONTROL_START_INITIAL = 1<<8; 2337663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn 23404ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown /** 23504ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown * Timeout in milliseconds for delivering a key to an IME. 23604ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown */ 23704ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown static final long INPUT_METHOD_NOT_RESPONDING_TIMEOUT = 2500; 23804ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown 239f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown /** @hide */ 240f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown public static final int DISPATCH_IN_PROGRESS = -1; 241f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 242f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown /** @hide */ 243f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown public static final int DISPATCH_NOT_HANDLED = 0; 244f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 245f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown /** @hide */ 246f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown public static final int DISPATCH_HANDLED = 1; 24704ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IInputMethodManager mService; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Looper mMainLooper; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // For scheduling work on the main thread. This also serves as our 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // global lock. 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final H mH; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Our generic input connection if the current target does not have its own. 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IInputContext mIInputContext; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * True if this input method client is active, initially false. 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mActive = false; 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set whenever this client becomes inactive, to know we need to reset 2657663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn * state with the IME the next time we receive focus. 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mHasBeenInactive = true; 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * As reported by IME through InputConnection. 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mFullscreenMode; 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ----------------------------------------------------------- 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the root view of the overall window that currently has input 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * method focus. 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View mCurRootView; 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is the view that should currently be served by an input method, 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * regardless of the state of setting that up. 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View mServedView; 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is then next view that will be served by the input method, when 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * we get around to updating things. 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View mNextServedView; 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is set when we are in the process of connecting, to determine 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when we have actually finished. 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mServedConnecting; 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This is non-null when we have connected the served view; it holds 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the attributes that were last retrieved from the served view and given 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to the input connection. 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EditorInfo mCurrentTextBoxAttribute; 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The InputConnection that was last retrieved from the served view. 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputConnection mServedInputConnection; 306ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn ControlledInputConnectionWrapper mServedInputConnectionWrapper; 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The completions that were last provided by the served view. 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CompletionInfo[] mCompletions; 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Cursor position on the screen. 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rect mTmpCursorRect = new Rect(); 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Rect mCursorRect = new Rect(); 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mCursorSelStart; 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mCursorSelEnd; 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mCursorCandStart; 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mCursorCandEnd; 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ----------------------------------------------------------- 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sequence number of this binding, as returned by the server. 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mBindSequence = -1; 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ID of the method we are bound to. 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mCurId; 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The actual instance of the method to make calls on it. 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IInputMethodSession mCurMethod; 334c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown InputChannel mCurChannel; 335c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ImeInputEventSender mCurSender; 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 337f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown final Pool<PendingEvent> mPendingEventPool = new SimplePool<PendingEvent>(20); 338f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown final SparseArray<PendingEvent> mPendingEvents = new SparseArray<PendingEvent>(20); 33904ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ----------------------------------------------------------- 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int MSG_DUMP = 1; 3434df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project static final int MSG_BIND = 2; 3444df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project static final int MSG_UNBIND = 3; 3454df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project static final int MSG_SET_ACTIVE = 4; 346f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown static final int MSG_SEND_INPUT_EVENT = 5; 347f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown static final int MSG_TIMEOUT_INPUT_EVENT = 6; 348f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown static final int MSG_FLUSH_INPUT_EVENT = 7; 349f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class H extends Handler { 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project H(Looper looper) { 35229c0ed2c130521ce1b648dd517a0d25457004de3Jeff Brown super(looper, null, true); 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (msg.what) { 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MSG_DUMP: { 359758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov SomeArgs args = (SomeArgs)msg.obj; 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project doDump((FileDescriptor)args.arg1, 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (PrintWriter)args.arg2, (String[])args.arg3); 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException e) { 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((PrintWriter)args.arg2).println("Exception: " + e); 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (args.arg4) { 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((CountDownLatch)args.arg4).countDown(); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 369758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov args.recycle(); 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3724df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project case MSG_BIND: { 3734df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project final InputBindResult res = (InputBindResult)msg.obj; 3744e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka if (DEBUG) { 3754e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka Log.i(TAG, "handleMessage: MSG_BIND " + res.sequence + "," + res.id); 3764e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka } 3774df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project synchronized (mH) { 3784df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (mBindSequence < 0 || mBindSequence != res.sequence) { 3794df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project Log.w(TAG, "Ignoring onBind: cur seq=" + mBindSequence 3804df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project + ", given seq=" + res.sequence); 3814d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown if (res.channel != null && res.channel != mCurChannel) { 382c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown res.channel.dispose(); 383c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 3844df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return; 3854df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 3864d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown 3874d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown setInputChannelLocked(res.channel); 3884df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mCurMethod = res.method; 3894df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mCurId = res.id; 3904df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mBindSequence = res.sequence; 3914df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 3927663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn startInputInner(null, 0, 0, 0); 3934df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return; 3944df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 3954df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project case MSG_UNBIND: { 3964df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project final int sequence = msg.arg1; 3974e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka if (DEBUG) { 3984e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka Log.i(TAG, "handleMessage: MSG_UNBIND " + sequence); 3994e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka } 40006a591cdd6d90600db006906d5d1524d156d6529Dianne Hackborn boolean startInput = false; 4014df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project synchronized (mH) { 4024df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (mBindSequence == sequence) { 4034df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (false) { 4044df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // XXX the server has already unbound! 4054df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (mCurMethod != null && mCurrentTextBoxAttribute != null) { 4064df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project try { 4074df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mCurMethod.finishInput(); 4084df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } catch (RemoteException e) { 4094df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project Log.w(TAG, "IME died: " + mCurId, e); 4104df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 4114df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 4124df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 4134df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project clearBindingLocked(); 4144df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 4154df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // If we were actively using the last input method, then 4164df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // we would like to re-connect to the next input method. 4174df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (mServedView != null && mServedView.isFocused()) { 4184df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mServedConnecting = true; 4194df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 420a82ba54b0bbc3ff41f29db3998806cb45b261d58Dianne Hackborn if (mActive) { 42106a591cdd6d90600db006906d5d1524d156d6529Dianne Hackborn startInput = true; 422a82ba54b0bbc3ff41f29db3998806cb45b261d58Dianne Hackborn } 4234df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 4244df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 42506a591cdd6d90600db006906d5d1524d156d6529Dianne Hackborn if (startInput) { 4267663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn startInputInner(null, 0, 0, 0); 42706a591cdd6d90600db006906d5d1524d156d6529Dianne Hackborn } 4284df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return; 4294df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 4304df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project case MSG_SET_ACTIVE: { 4314df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project final boolean active = msg.arg1 != 0; 4324e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka if (DEBUG) { 4334e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka Log.i(TAG, "handleMessage: MSG_SET_ACTIVE " + active + ", was " + mActive); 4344e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka } 4354df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project synchronized (mH) { 4364df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mActive = active; 4374df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mFullscreenMode = false; 4384df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (!active) { 4394df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // Some other client has starting using the IME, so note 4404df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // that this happened and make sure our own editor's 4414df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // state is reset. 4424df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mHasBeenInactive = true; 4434df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project try { 4444df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // Note that finishComposingText() is allowed to run 4454df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project // even when we are not active. 4464df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mIInputContext.finishComposingText(); 4474df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } catch (RemoteException e) { 4484df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 44931e4e149941e34cd135dfa0b6d918cc0b3dabbbcsatok // Check focus again in case that "onWindowFocus" is called before 45031e4e149941e34cd135dfa0b6d918cc0b3dabbbcsatok // handling this message. 45105a6cbe2863614a1761adc033c905458b27be47esatok if (mServedView != null && mServedView.hasWindowFocus()) { 4524e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka // "finishComposingText" has been already called above. So we 4534e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka // should not call mServedInputConnection.finishComposingText here. 4544e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka // Also, please note that this handler thread could be different 4554e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka // from a thread that created mServedView. That could happen 4564e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka // the current activity is running in the system process. 4574e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka // In that case, we really should not call 4584e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka // mServedInputConnection.finishComposingText. 4594e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka if (checkFocusNoStartInput(mHasBeenInactive, false)) { 4604e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka startInputInner(null, 0, 0, 0); 4614e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka } 46205a6cbe2863614a1761adc033c905458b27be47esatok } 4634df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 4644df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 4654df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return; 4664df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 467f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown case MSG_SEND_INPUT_EVENT: { 468f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown sendInputEventAndReportResultOnMainLooper((PendingEvent)msg.obj); 469f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown return; 470f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown } 471f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown case MSG_TIMEOUT_INPUT_EVENT: { 472f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown finishedInputEvent(msg.arg1, false, true); 473f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown return; 474f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown } 475f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown case MSG_FLUSH_INPUT_EVENT: { 476f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown finishedInputEvent(msg.arg1, false, false); 47704ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown return; 47804ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown } 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 483de9dbb05ce57a1617efc131f6a724c2a2b164bf7Jean Chalard private static class ControlledInputConnectionWrapper extends IInputConnectionWrapper { 484de9dbb05ce57a1617efc131f6a724c2a2b164bf7Jean Chalard private final InputMethodManager mParentInputMethodManager; 485ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn private boolean mActive; 486de9dbb05ce57a1617efc131f6a724c2a2b164bf7Jean Chalard 487de9dbb05ce57a1617efc131f6a724c2a2b164bf7Jean Chalard public ControlledInputConnectionWrapper(final Looper mainLooper, final InputConnection conn, 488de9dbb05ce57a1617efc131f6a724c2a2b164bf7Jean Chalard final InputMethodManager inputMethodManager) { 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(mainLooper, conn); 490de9dbb05ce57a1617efc131f6a724c2a2b164bf7Jean Chalard mParentInputMethodManager = inputMethodManager; 491ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn mActive = true; 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4948cbb4c6e30cff706a243599634aeb8fd9a818d92Gilles Debunne @Override 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isActive() { 496ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn return mParentInputMethodManager.mActive && mActive; 497ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn } 498ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn 499ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn void deactivate() { 500ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn mActive = false; 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IInputMethodClient.Stub mClient = new IInputMethodClient.Stub() { 505c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown @Override 506c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // No need to check for dump permission, since we only give this 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // interface to the system. 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CountDownLatch latch = new CountDownLatch(1); 510758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov SomeArgs sargs = SomeArgs.obtain(); 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sargs.arg1 = fd; 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sargs.arg2 = fout; 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sargs.arg3 = args; 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sargs.arg4 = latch; 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mH.sendMessage(mH.obtainMessage(MSG_DUMP, sargs)); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!latch.await(5, TimeUnit.SECONDS)) { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fout.println("Timeout waiting for dump"); 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fout.println("Interrupted waiting for dump"); 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 524c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 525c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown @Override 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setUsingInputMethod(boolean state) { 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 528c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 529c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown @Override 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onBindMethod(InputBindResult res) { 5314df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mH.sendMessage(mH.obtainMessage(MSG_BIND, res)); 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 533c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 534c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown @Override 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onUnbindMethod(int sequence) { 5364df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mH.sendMessage(mH.obtainMessage(MSG_UNBIND, sequence, 0)); 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 538c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 539c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown @Override 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setActive(boolean active) { 5414df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mH.sendMessage(mH.obtainMessage(MSG_SET_ACTIVE, active ? 1 : 0, 0)); 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 543c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown }; 544c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 54551bf077883df4f5cc816fbfec6d19eedffc26d70Dianne Hackborn final InputConnection mDummyInputConnection = new BaseInputConnection(this, false); 54604ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputMethodManager(IInputMethodManager service, Looper looper) { 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mService = service; 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMainLooper = looper; 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mH = new H(looper); 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIInputContext = new ControlledInputConnectionWrapper(looper, 552de9dbb05ce57a1617efc131f6a724c2a2b164bf7Jean Chalard mDummyInputConnection, this); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Retrieve the global InputMethodManager instance, creating it if it 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * doesn't already exist. 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 560f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown public static InputMethodManager getInstance() { 561f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown synchronized (InputMethodManager.class) { 562f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown if (sInstance == null) { 563f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown IBinder b = ServiceManager.getService(Context.INPUT_METHOD_SERVICE); 564f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown IInputMethodManager service = IInputMethodManager.Stub.asInterface(b); 565f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown sInstance = new InputMethodManager(service, Looper.getMainLooper()); 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 567f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown return sInstance; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Private optimization: retrieve the global InputMethodManager instance, 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if it exists. 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 576f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown public static InputMethodManager peekInstance() { 577f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown return sInstance; 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public IInputMethodClient getClient() { 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mClient; 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public IInputContext getInputContext() { 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mIInputContext; 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<InputMethodInfo> getInputMethodList() { 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mService.getInputMethodList(); 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException(e); 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<InputMethodInfo> getEnabledInputMethodList() { 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mService.getEnabledInputMethodList(); 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException(e); 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 606d4fce2b7f1a861590ce84afcf2f569189251bc59satok /** 607d4fce2b7f1a861590ce84afcf2f569189251bc59satok * Returns a list of enabled input method subtypes for the specified input method info. 608d4fce2b7f1a861590ce84afcf2f569189251bc59satok * @param imi An input method info whose subtypes list will be returned. 609d4fce2b7f1a861590ce84afcf2f569189251bc59satok * @param allowsImplicitlySelectedSubtypes A boolean flag to allow to return the implicitly 610d4fce2b7f1a861590ce84afcf2f569189251bc59satok * selected subtypes. If an input method info doesn't have enabled subtypes, the framework 611d4fce2b7f1a861590ce84afcf2f569189251bc59satok * will implicitly enable subtypes according to the current system language. 612d4fce2b7f1a861590ce84afcf2f569189251bc59satok */ 61316331c8a1d33defccc5cbb18694def79196c921bsatok public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(InputMethodInfo imi, 61416331c8a1d33defccc5cbb18694def79196c921bsatok boolean allowsImplicitlySelectedSubtypes) { 61567ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok try { 616b3c21ac7c661022534135bf688a75ec35fe3a8f2Satoshi Kataoka return mService.getEnabledInputMethodSubtypeList( 617b3c21ac7c661022534135bf688a75ec35fe3a8f2Satoshi Kataoka imi == null ? null : imi.getId(), allowsImplicitlySelectedSubtypes); 61867ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok } catch (RemoteException e) { 61967ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok throw new RuntimeException(e); 62067ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok } 62167ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok } 62267ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showStatusIcon(IBinder imeToken, String packageName, int iconId) { 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mService.updateStatusIcon(imeToken, packageName, iconId); 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException(e); 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void hideStatusIcon(IBinder imeToken) { 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mService.updateStatusIcon(imeToken, null, 0); 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException(e); 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 640857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato public void setImeWindowStatus(IBinder imeToken, int vis, int backDisposition) { 64106487a58be22b100daf3f950b9a1d25c3ea42aa2satok try { 642857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mService.setImeWindowStatus(imeToken, vis, backDisposition); 64306487a58be22b100daf3f950b9a1d25c3ea42aa2satok } catch (RemoteException e) { 64406487a58be22b100daf3f950b9a1d25c3ea42aa2satok throw new RuntimeException(e); 64506487a58be22b100daf3f950b9a1d25c3ea42aa2satok } 64606487a58be22b100daf3f950b9a1d25c3ea42aa2satok } 64706487a58be22b100daf3f950b9a1d25c3ea42aa2satok 64806487a58be22b100daf3f950b9a1d25c3ea42aa2satok /** @hide */ 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setFullscreenMode(boolean fullScreen) { 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFullscreenMode = fullScreen; 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 652f9f01008624e2d28c15a90d942fa36f98c8c967dsatok 653f9f01008624e2d28c15a90d942fa36f98c8c967dsatok /** @hide */ 654f9f01008624e2d28c15a90d942fa36f98c8c967dsatok public void registerSuggestionSpansForNotification(SuggestionSpan[] spans) { 655f9f01008624e2d28c15a90d942fa36f98c8c967dsatok try { 656f9f01008624e2d28c15a90d942fa36f98c8c967dsatok mService.registerSuggestionSpansForNotification(spans); 657f9f01008624e2d28c15a90d942fa36f98c8c967dsatok } catch (RemoteException e) { 658f9f01008624e2d28c15a90d942fa36f98c8c967dsatok throw new RuntimeException(e); 659f9f01008624e2d28c15a90d942fa36f98c8c967dsatok } 660f9f01008624e2d28c15a90d942fa36f98c8c967dsatok } 661f9f01008624e2d28c15a90d942fa36f98c8c967dsatok 662f9f01008624e2d28c15a90d942fa36f98c8c967dsatok /** @hide */ 663f9f01008624e2d28c15a90d942fa36f98c8c967dsatok public void notifySuggestionPicked(SuggestionSpan span, String originalString, int index) { 664f9f01008624e2d28c15a90d942fa36f98c8c967dsatok try { 665f9f01008624e2d28c15a90d942fa36f98c8c967dsatok mService.notifySuggestionPicked(span, originalString, index); 666f9f01008624e2d28c15a90d942fa36f98c8c967dsatok } catch (RemoteException e) { 667f9f01008624e2d28c15a90d942fa36f98c8c967dsatok throw new RuntimeException(e); 668f9f01008624e2d28c15a90d942fa36f98c8c967dsatok } 669f9f01008624e2d28c15a90d942fa36f98c8c967dsatok } 670f9f01008624e2d28c15a90d942fa36f98c8c967dsatok 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Allows you to discover whether the attached input method is running 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * in fullscreen mode. Return true if it is fullscreen, entirely covering 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * your UI, else returns false. 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isFullscreenMode() { 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFullscreenMode; 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return true if the given view is the currently active view for the 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * input method. 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isActive(View view) { 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkFocus(); 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 687b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project return (mServedView == view 688b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project || (mServedView != null 689b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project && mServedView.checkInputConnectionProxy(view))) 690b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project && mCurrentTextBoxAttribute != null; 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 * Return true if any view is currently active in the input method. 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isActive() { 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkFocus(); 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mServedView != null && mCurrentTextBoxAttribute != null; 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return true if the currently served view is accepting full text edits. 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If false, it has no input connection, so can only handle raw key events. 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isAcceptingText() { 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkFocus(); 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mServedInputConnection != null; 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Reset all of the state associated with being bound to an input method. 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void clearBindingLocked() { 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clearConnectionLocked(); 7184d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown setInputChannelLocked(null); 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBindSequence = -1; 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurId = null; 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurMethod = null; 7224d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown } 7234d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown 7244d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown void setInputChannelLocked(InputChannel channel) { 7254d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown if (mCurChannel != channel) { 7264d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown if (mCurSender != null) { 7274d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown flushPendingEventsLocked(); 7284d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown mCurSender.dispose(); 7294d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown mCurSender = null; 7304d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown } 7314d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown if (mCurChannel != null) { 7324d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown mCurChannel.dispose(); 7334d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown } 7344d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown mCurChannel = channel; 735c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7374d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Reset all of the state associated with a served view being connected 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to an input method 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void clearConnectionLocked() { 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrentTextBoxAttribute = null; 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServedInputConnection = null; 745ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn if (mServedInputConnectionWrapper != null) { 746ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn mServedInputConnectionWrapper.deactivate(); 747ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn mServedInputConnectionWrapper = null; 748ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn } 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Disconnect any existing input connection, clearing the served view. 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void finishInputLocked() { 7554478de3c02c1fb2f4f888e696ee1b13721e936d9Jeff Sharkey mCurRootView = null; 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextServedView = null; 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mServedView != null) { 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "FINISH INPUT: " + mServedView); 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrentTextBoxAttribute != null) { 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mService.finishInput(mClient); 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 767c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne notifyInputConnectionFinished(); 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServedView = null; 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompletions = null; 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServedConnecting = false; 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project clearConnectionLocked(); 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 775c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne 776c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne /** 777c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne * Notifies the served view that the current InputConnection will no longer be used. 778c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne */ 779c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne private void notifyInputConnectionFinished() { 780c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne if (mServedView != null && mServedInputConnection != null) { 781c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne // We need to tell the previously served view that it is no 782c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne // longer the input target, so it can reset its state. Schedule 783c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne // this call on its window's Handler so it will be on the correct 784c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne // thread and outside of our lock. 785a175a5b7ea3682cb58cca7f9726d0b8171cd549dJeff Brown ViewRootImpl viewRootImpl = mServedView.getViewRootImpl(); 786a175a5b7ea3682cb58cca7f9726d0b8171cd549dJeff Brown if (viewRootImpl != null) { 787c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne // This will result in a call to reportFinishInputConnection() below. 788a175a5b7ea3682cb58cca7f9726d0b8171cd549dJeff Brown viewRootImpl.dispatchFinishInputConnection(mServedInputConnection); 789c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne } 790c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne } 791c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne } 792c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Called from the FINISH_INPUT_CONNECTION message above. 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void reportFinishInputConnection(InputConnection ic) { 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mServedInputConnection != ic) { 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ic.finishComposingText(); 8009d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne // To avoid modifying the public InputConnection interface 8019d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne if (ic instanceof BaseInputConnection) { 8029d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne ((BaseInputConnection) ic).reportFinish(); 8039d69ecbf61a4a142c3f4cbb9d5659faa6f85e832Gilles Debunne } 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 806c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void displayCompletions(View view, CompletionInfo[] completions) { 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkFocus(); 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 810b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project if (mServedView != view && (mServedView == null 811b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project || !mServedView.checkInputConnectionProxy(view))) { 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompletions = completions; 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurMethod != null) { 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurMethod.displayCompletions(mCompletions); 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void updateExtractedText(View view, int token, ExtractedText text) { 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkFocus(); 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 828b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project if (mServedView != view && (mServedView == null 829b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project || !mServedView.checkInputConnectionProxy(view))) { 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurMethod != null) { 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurMethod.updateExtractedText(token, text); 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Flag for {@link #showSoftInput} to indicate that this is an implicit 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * request to show the input window, not as the result of a direct request 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the user. The window may not be shown in this case. 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SHOW_IMPLICIT = 0x0001; 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Flag for {@link #showSoftInput} to indicate that the user has forced 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the input method open (such as by long-pressing menu) so it should 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * not be closed until they explicitly do so. 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int SHOW_FORCED = 0x0002; 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8574df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * Synonym for {@link #showSoftInput(View, int, ResultReceiver)} without 8584df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * a result receiver: explicitly request that the current input method's 8594df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * soft input area be shown to the user, if needed. 8604df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * 8614df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * @param view The currently focused view, which would like to receive 8624df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * soft keyboard input. 8634df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * @param flags Provides additional operating flags. Currently may be 8644df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * 0 or have the {@link #SHOW_IMPLICIT} bit set. 8654df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project */ 8664df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public boolean showSoftInput(View view, int flags) { 8674df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return showSoftInput(view, flags, null); 8684df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 8694df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 8704df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project /** 8714df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * Flag for the {@link ResultReceiver} result code from 8724df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #showSoftInput(View, int, ResultReceiver)} and 8734df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #hideSoftInputFromWindow(IBinder, int, ResultReceiver)}: the 8744df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * state of the soft input window was unchanged and remains shown. 8754df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project */ 8764df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public static final int RESULT_UNCHANGED_SHOWN = 0; 8774df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 8784df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project /** 8794df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * Flag for the {@link ResultReceiver} result code from 8804df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #showSoftInput(View, int, ResultReceiver)} and 8814df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #hideSoftInputFromWindow(IBinder, int, ResultReceiver)}: the 8824df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * state of the soft input window was unchanged and remains hidden. 8834df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project */ 8844df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public static final int RESULT_UNCHANGED_HIDDEN = 1; 8854df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 8864df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project /** 8874df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * Flag for the {@link ResultReceiver} result code from 8884df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #showSoftInput(View, int, ResultReceiver)} and 8894df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #hideSoftInputFromWindow(IBinder, int, ResultReceiver)}: the 8904df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * state of the soft input window changed from hidden to shown. 8914df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project */ 8924df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public static final int RESULT_SHOWN = 2; 8934df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 8944df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project /** 8954df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * Flag for the {@link ResultReceiver} result code from 8964df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #showSoftInput(View, int, ResultReceiver)} and 8974df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #hideSoftInputFromWindow(IBinder, int, ResultReceiver)}: the 8984df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * state of the soft input window changed from shown to hidden. 8994df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project */ 9004df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public static final int RESULT_HIDDEN = 3; 9014df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 9024df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project /** 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Explicitly request that the current input method's soft input area be 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * shown to the user, if needed. Call this if the user interacts with 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * your view in such a way that they have expressed they would like to 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * start performing input into it. 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param view The currently focused view, which would like to receive 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * soft keyboard input. 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param flags Provides additional operating flags. Currently may be 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 0 or have the {@link #SHOW_IMPLICIT} bit set. 9124df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * @param resultReceiver If non-null, this will be called by the IME when 9134df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * it has processed your request to tell you what it has done. The result 9144df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * code you receive may be either {@link #RESULT_UNCHANGED_SHOWN}, 9154df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #RESULT_UNCHANGED_HIDDEN}, {@link #RESULT_SHOWN}, or 9164df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #RESULT_HIDDEN}. 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 918ad8484b3799ba7046e57388e34ba9a4c0a971b42Gilles Debunne public boolean showSoftInput(View view, int flags, ResultReceiver resultReceiver) { 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkFocus(); 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 921b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project if (mServedView != view && (mServedView == null 922b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project || !mServedView.checkInputConnectionProxy(view))) { 9234df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return false; 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9274df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return mService.showSoftInput(mClient, flags, resultReceiver); 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9304df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 9314df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return false; 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 9364df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public void showSoftInputUnchecked(int flags, ResultReceiver resultReceiver) { 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9384df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mService.showSoftInput(mClient, flags, resultReceiver); 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Flag for {@link #hideSoftInputFromWindow} to indicate that the soft 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * input window should only be hidden if it was not explicitly shown 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * by the user. 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int HIDE_IMPLICIT_ONLY = 0x0001; 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Flag for {@link #hideSoftInputFromWindow} to indicate that the soft 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * input window should normally be hidden, unless it was originally 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * shown with {@link #SHOW_FORCED}. 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int HIDE_NOT_ALWAYS = 0x0002; 956c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9587c8c6d689280ecfbd151a2e0cb40341768470676Gilles Debunne * Synonym for {@link #hideSoftInputFromWindow(IBinder, int, ResultReceiver)} 9594df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * without a result: request to hide the soft input window from the 9604df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * context of the window that is currently accepting input. 9614df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * 9624df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * @param windowToken The token of the window that is making the request, 9634df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * as returned by {@link View#getWindowToken() View.getWindowToken()}. 9644df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * @param flags Provides additional operating flags. Currently may be 9654df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * 0 or have the {@link #HIDE_IMPLICIT_ONLY} bit set. 9664df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project */ 9674df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public boolean hideSoftInputFromWindow(IBinder windowToken, int flags) { 9684df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return hideSoftInputFromWindow(windowToken, flags, null); 9694df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 9704df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 9714df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project /** 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Request to hide the soft input window from the context of the window 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that is currently accepting input. This should be called as a result 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the user doing some actually than fairly explicitly requests to 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * have the input window hidden. 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param windowToken The token of the window that is making the request, 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * as returned by {@link View#getWindowToken() View.getWindowToken()}. 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param flags Provides additional operating flags. Currently may be 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 0 or have the {@link #HIDE_IMPLICIT_ONLY} bit set. 9814df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * @param resultReceiver If non-null, this will be called by the IME when 9824df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * it has processed your request to tell you what it has done. The result 9834df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * code you receive may be either {@link #RESULT_UNCHANGED_SHOWN}, 9844df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #RESULT_UNCHANGED_HIDDEN}, {@link #RESULT_SHOWN}, or 9854df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #RESULT_HIDDEN}. 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9874df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public boolean hideSoftInputFromWindow(IBinder windowToken, int flags, 9884df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project ResultReceiver resultReceiver) { 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkFocus(); 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mServedView == null || mServedView.getWindowToken() != windowToken) { 9924df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return false; 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9964df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return mService.hideSoftInput(mClient, flags, resultReceiver); 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9994df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return false; 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10034df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 10044df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project /** 10054df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * This method toggles the input method window display. 10064df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * If the input window is already displayed, it gets hidden. 10074df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * If not the input window will be displayed. 10084df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * @param windowToken The token of the window that is making the request, 10094df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * as returned by {@link View#getWindowToken() View.getWindowToken()}. 10104df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * @param showFlags Provides additional operating flags. May be 10114df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * 0 or have the {@link #SHOW_IMPLICIT}, 10124df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #SHOW_FORCED} bit set. 10134df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * @param hideFlags Provides additional operating flags. May be 10144df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * 0 or have the {@link #HIDE_IMPLICIT_ONLY}, 10154df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #HIDE_NOT_ALWAYS} bit set. 10164df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project **/ 10174df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public void toggleSoftInputFromWindow(IBinder windowToken, int showFlags, int hideFlags) { 10184df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project synchronized (mH) { 10194df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (mServedView == null || mServedView.getWindowToken() != windowToken) { 10204df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return; 10214df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 10224df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (mCurMethod != null) { 10234df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project try { 10244df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mCurMethod.toggleSoftInput(showFlags, hideFlags); 10254df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } catch (RemoteException e) { 10264df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 10274df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 10284df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 10294df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 10304df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 10314df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project /* 10324df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * This method toggles the input method window display. 10334df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * If the input window is already displayed, it gets hidden. 10344df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * If not the input window will be displayed. 10354df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * @param showFlags Provides additional operating flags. May be 10364df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * 0 or have the {@link #SHOW_IMPLICIT}, 10374df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #SHOW_FORCED} bit set. 10384df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * @param hideFlags Provides additional operating flags. May be 10394df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * 0 or have the {@link #HIDE_IMPLICIT_ONLY}, 10404df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #HIDE_NOT_ALWAYS} bit set. 10414df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * @hide 10424df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project */ 10434df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public void toggleSoftInput(int showFlags, int hideFlags) { 10444df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (mCurMethod != null) { 10454df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project try { 10464df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mCurMethod.toggleSoftInput(showFlags, hideFlags); 10474df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } catch (RemoteException e) { 10484df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 10494df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 10504df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 10514df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the input method is currently connected to the given view, 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * restart it with its new contents. You should call this when the text 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * within your view changes outside of the normal input method or key 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * input flow, such as when an application calls TextView.setText(). 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param view The view whose text has changed. 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void restartInput(View view) { 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkFocus(); 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 1063b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project if (mServedView != view && (mServedView == null 1064b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project || !mServedView.checkInputConnectionProxy(view))) { 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServedConnecting = true; 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10717663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn startInputInner(null, 0, 0, 0); 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10747663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn boolean startInputInner(IBinder windowGainingFocus, int controlFlags, int softInputMode, 10757663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn int windowFlags) { 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final View view; 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project view = mServedView; 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Make sure we have a window token for the served view. 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "Starting input: view=" + view); 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (view == null) { 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "ABORT input: no served view!"); 10847663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn return false; 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Now we need to get an input connection from the served view. 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is complicated in a couple ways: we can't be holding our lock 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // when calling out to the view, and we need to make sure we call into 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the view on the same thread that is driving its view hierarchy. 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Handler vh = view.getHandler(); 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (vh == null) { 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the view doesn't have a handler, something has changed out 10953573950e0b30178dc963de3fa00aba2ebcfd552dSatoshi Kataoka // from under us, so just close the current input. 10963573950e0b30178dc963de3fa00aba2ebcfd552dSatoshi Kataoka // If we don't close the current input, the current input method can remain on the 10973573950e0b30178dc963de3fa00aba2ebcfd552dSatoshi Kataoka // screen without a connection. 10983573950e0b30178dc963de3fa00aba2ebcfd552dSatoshi Kataoka if (DEBUG) Log.v(TAG, "ABORT input: no handler for view! Close current input."); 10993573950e0b30178dc963de3fa00aba2ebcfd552dSatoshi Kataoka closeCurrentInput(); 11007663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn return false; 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (vh.getLooper() != Looper.myLooper()) { 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The view is running on a different thread than our own, so 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we need to reschedule our work for over there. 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "Starting input: reschedule to view thread"); 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project vh.post(new Runnable() { 1107c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown @Override 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 11097663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn startInputInner(null, 0, 0, 0); 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }); 11127663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn return false; 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Okay we are now ready to call into the served view and have it 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // do its stuff. 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Life is good: let's hook everything up! 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EditorInfo tba = new EditorInfo(); 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tba.packageName = view.getContext().getPackageName(); 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project tba.fieldId = view.getId(); 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputConnection ic = view.onCreateInputConnection(tba); 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "Starting input: tba=" + tba + " ic=" + ic); 1123c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Now that we are locked again, validate that our state hasn't 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // changed. 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mServedView != view || !mServedConnecting) { 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Something else happened, so abort. 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Starting input: finished by someone else (view=" 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mServedView + " conn=" + mServedConnecting + ")"); 11327663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn return false; 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11347663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we already have a text box, then this view is already 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // connected so we want to restart it. 11377663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn if (mCurrentTextBoxAttribute == null) { 11387663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn controlFlags |= CONTROL_START_INITIAL; 11397663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn } 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Hook 'em up and let 'er rip. 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrentTextBoxAttribute = tba; 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServedConnecting = false; 1144c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne // Notify the served view that its previous input connection is finished 1145c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne notifyInputConnectionFinished(); 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServedInputConnection = ic; 1147ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn ControlledInputConnectionWrapper servedContext; 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ic != null) { 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCursorSelStart = tba.initialSelStart; 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCursorSelEnd = tba.initialSelEnd; 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCursorCandStart = -1; 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCursorCandEnd = -1; 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCursorRect.setEmpty(); 1154de9dbb05ce57a1617efc131f6a724c2a2b164bf7Jean Chalard servedContext = new ControlledInputConnectionWrapper(vh.getLooper(), ic, this); 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project servedContext = null; 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1158ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn if (mServedInputConnectionWrapper != null) { 1159ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn mServedInputConnectionWrapper.deactivate(); 1160ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn } 1161ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn mServedInputConnectionWrapper = servedContext; 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "START INPUT: " + view + " ic=" 11657663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn + ic + " tba=" + tba + " controlFlags=#" 11667663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn + Integer.toHexString(controlFlags)); 11677663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn InputBindResult res; 11687663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn if (windowGainingFocus != null) { 11697663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn res = mService.windowGainedFocus(mClient, windowGainingFocus, 11707663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn controlFlags, softInputMode, windowFlags, 11717663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn tba, servedContext); 11727663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn } else { 11737663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn res = mService.startInput(mClient, 11747663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn servedContext, tba, controlFlags); 11757663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn } 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res); 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (res != null) { 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (res.id != null) { 11794d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown setInputChannelLocked(res.channel); 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBindSequence = res.sequence; 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurMethod = res.method; 118204ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown mCurId = res.id; 1183c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } else { 11844d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown if (res.channel != null && res.channel != mCurChannel) { 1185c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown res.channel.dispose(); 1186c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 1187c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (mCurMethod == null) { 1188c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown // This means there is no input method available. 1189c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (DEBUG) Log.v(TAG, "ABORT input: no input method!"); 1190c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return true; 1191c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurMethod != null && mCompletions != null) { 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurMethod.displayCompletions(mCompletions); 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "IME died: " + mCurId, e); 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12047663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn 12057663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn return true; 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * When the focused window is dismissed, this method is called to finish the 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * input method started before. 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void windowDismissed(IBinder appWindowToken) { 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkFocus(); 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mServedView != null && 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServedView.getWindowToken() == appWindowToken) { 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project finishInputLocked(); 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Call this when a view receives focus. 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void focusIn(View view) { 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project focusInLocked(view); 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void focusInLocked(View view) { 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "focusIn: " + view); 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurRootView != view.getRootView()) { 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is a request from a window that isn't in the window with 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // IME focus, so ignore it. 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "Not IME target window, ignoring"); 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextServedView = view; 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleCheckFocusLocked(view); 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Call this when a view loses focus. 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void focusOut(View view) { 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "focusOut: " + view 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " mServedView=" + mServedView 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " winFocus=" + view.hasWindowFocus()); 1256b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project if (mServedView != view) { 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The following code would auto-hide the IME if we end up 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // with no more views with focus. This can happen, however, 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // whenever we go into touch mode, so it ends up hiding 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // at times when we don't really want it to. For now it 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // seems better to just turn it all off. 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (false && view.hasWindowFocus()) { 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextServedView = null; 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project scheduleCheckFocusLocked(view); 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 1270c478c171e92b2f255e9699d9c9306b001368ac20Gilles Debunne static void scheduleCheckFocusLocked(View view) { 1271a175a5b7ea3682cb58cca7f9726d0b8171cd549dJeff Brown ViewRootImpl viewRootImpl = view.getViewRootImpl(); 1272a175a5b7ea3682cb58cca7f9726d0b8171cd549dJeff Brown if (viewRootImpl != null) { 1273a175a5b7ea3682cb58cca7f9726d0b8171cd549dJeff Brown viewRootImpl.dispatchCheckFocus(); 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1276a175a5b7ea3682cb58cca7f9726d0b8171cd549dJeff Brown 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void checkFocus() { 12814e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka if (checkFocusNoStartInput(false, true)) { 12824e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka startInputInner(null, 0, 0, 0); 12834e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka } 1284a82ba54b0bbc3ff41f29db3998806cb45b261d58Dianne Hackborn } 1285a82ba54b0bbc3ff41f29db3998806cb45b261d58Dianne Hackborn 12864e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka private boolean checkFocusNoStartInput(boolean forceNewFocus, boolean finishComposingText) { 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This is called a lot, so short-circuit before locking. 12887663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn if (mServedView == mNextServedView && !forceNewFocus) { 1289a82ba54b0bbc3ff41f29db3998806cb45b261d58Dianne Hackborn return false; 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1291863fcd62171e55bc9f2105d9fb5877df982454d8satok 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputConnection ic = null; 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 12947663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn if (mServedView == mNextServedView && !forceNewFocus) { 1295a82ba54b0bbc3ff41f29db3998806cb45b261d58Dianne Hackborn return false; 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "checkFocus: view=" + mServedView 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " next=" + mNextServedView 129905a6cbe2863614a1761adc033c905458b27be47esatok + " forceNewFocus=" + forceNewFocus 130005a6cbe2863614a1761adc033c905458b27be47esatok + " package=" 130105a6cbe2863614a1761adc033c905458b27be47esatok + (mServedView != null ? mServedView.getContext().getPackageName() : "<none>")); 1302a82ba54b0bbc3ff41f29db3998806cb45b261d58Dianne Hackborn 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNextServedView == null) { 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project finishInputLocked(); 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // In this case, we used to have a focused view on the window, 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // but no longer do. We should make sure the input method is 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // no longer shown, since it serves no purpose. 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project closeCurrentInput(); 1309a82ba54b0bbc3ff41f29db3998806cb45b261d58Dianne Hackborn return false; 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1311a82ba54b0bbc3ff41f29db3998806cb45b261d58Dianne Hackborn 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ic = mServedInputConnection; 1313a82ba54b0bbc3ff41f29db3998806cb45b261d58Dianne Hackborn 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServedView = mNextServedView; 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrentTextBoxAttribute = null; 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompletions = null; 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mServedConnecting = true; 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1319a82ba54b0bbc3ff41f29db3998806cb45b261d58Dianne Hackborn 13204e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka if (finishComposingText && ic != null) { 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ic.finishComposingText(); 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1323a82ba54b0bbc3ff41f29db3998806cb45b261d58Dianne Hackborn 1324a82ba54b0bbc3ff41f29db3998806cb45b261d58Dianne Hackborn return true; 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void closeCurrentInput() { 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 13294df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mService.hideSoftInput(mClient, HIDE_NOT_ALWAYS, null); 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13337663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1335c6cc0f8c19d9eccf408a443fa2bf668af261dcd0Joe Onorato * Called by ViewAncestor when its window gets input focus. 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onWindowFocus(View rootView, View focusedView, int softInputMode, 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean first, int windowFlags) { 13407663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn boolean forceNewFocus = false; 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "onWindowFocus: " + focusedView 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " softInputMode=" + softInputMode 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " first=" + first + " flags=#" 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Integer.toHexString(windowFlags)); 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHasBeenInactive) { 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "Has been inactive! Starting fresh"); 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHasBeenInactive = false; 13497663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn forceNewFocus = true; 13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project focusInLocked(focusedView != null ? focusedView : rootView); 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13537663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn 13547663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn int controlFlags = 0; 13557663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn if (focusedView != null) { 13567663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn controlFlags |= CONTROL_WINDOW_VIEW_HAS_FOCUS; 13577663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn if (focusedView.onCheckIsTextEditor()) { 13587663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn controlFlags |= CONTROL_WINDOW_IS_TEXT_EDITOR; 13597663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn } 13607663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn } 13617663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn if (first) { 13627663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn controlFlags |= CONTROL_WINDOW_FIRST; 13637663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn } 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13654e5184f929d2498714bc7734fe10b9b8810cb071Satoshi Kataoka if (checkFocusNoStartInput(forceNewFocus, true)) { 13667663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn // We need to restart input on the current focus view. This 13677663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn // should be done in conjunction with telling the system service 13687663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn // about the window gaining focus, to help make the transition 13697663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn // smooth. 13707663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn if (startInputInner(rootView.getWindowToken(), 13717663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn controlFlags, softInputMode, windowFlags)) { 13727663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn return; 13737663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn } 13747663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn } 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13767663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn // For some reason we didn't do a startInput + windowFocusGain, so 13777663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn // we'll just do a window focus gain and call it a day. 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1380ac92087a9a1c464d4b0a58c82dae01cbaa088e89Dianne Hackborn if (DEBUG) Log.v(TAG, "Reporting focus gain, without startInput"); 1381b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project mService.windowGainedFocus(mClient, rootView.getWindowToken(), 13827663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn controlFlags, softInputMode, windowFlags, null, null); 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** @hide */ 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startGettingWindowFocus(View rootView) { 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurRootView = rootView; 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Report the current selection range. 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void updateSelection(View view, int selStart, int selEnd, 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int candidatesStart, int candidatesEnd) { 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkFocus(); 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 1402b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project if ((mServedView != view && (mServedView == null 1403b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project || !mServedView.checkInputConnectionProxy(view))) 1404b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project || mCurrentTextBoxAttribute == null || mCurMethod == null) { 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCursorSelStart != selStart || mCursorSelEnd != selEnd 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || mCursorCandStart != candidatesStart 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || mCursorCandEnd != candidatesEnd) { 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.d(TAG, "updateSelection"); 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "SELECTION CHANGE: " + mCurMethod); 1415c743cb94770701ec20a01b57b09232f1aae5bcbbJean Chalard final int oldSelStart = mCursorSelStart; 1416c743cb94770701ec20a01b57b09232f1aae5bcbbJean Chalard final int oldSelEnd = mCursorSelEnd; 1417c743cb94770701ec20a01b57b09232f1aae5bcbbJean Chalard // Update internal values before sending updateSelection to the IME, because 1418c743cb94770701ec20a01b57b09232f1aae5bcbbJean Chalard // if it changes the text within its onUpdateSelection handler in a way that 1419c743cb94770701ec20a01b57b09232f1aae5bcbbJean Chalard // does not move the cursor we don't want to call it again with the same values. 14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCursorSelStart = selStart; 14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCursorSelEnd = selEnd; 14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCursorCandStart = candidatesStart; 14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCursorCandEnd = candidatesEnd; 1424c743cb94770701ec20a01b57b09232f1aae5bcbbJean Chalard mCurMethod.updateSelection(oldSelStart, oldSelEnd, 1425c743cb94770701ec20a01b57b09232f1aae5bcbbJean Chalard selStart, selEnd, candidatesStart, candidatesEnd); 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "IME died: " + mCurId, e); 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1434863fcd62171e55bc9f2105d9fb5877df982454d8satok * Notify the event when the user tapped or clicked the text view. 1435863fcd62171e55bc9f2105d9fb5877df982454d8satok */ 1436863fcd62171e55bc9f2105d9fb5877df982454d8satok public void viewClicked(View view) { 1437863fcd62171e55bc9f2105d9fb5877df982454d8satok final boolean focusChanged = mServedView != mNextServedView; 1438863fcd62171e55bc9f2105d9fb5877df982454d8satok checkFocus(); 1439863fcd62171e55bc9f2105d9fb5877df982454d8satok synchronized (mH) { 1440863fcd62171e55bc9f2105d9fb5877df982454d8satok if ((mServedView != view && (mServedView == null 1441863fcd62171e55bc9f2105d9fb5877df982454d8satok || !mServedView.checkInputConnectionProxy(view))) 1442863fcd62171e55bc9f2105d9fb5877df982454d8satok || mCurrentTextBoxAttribute == null || mCurMethod == null) { 1443863fcd62171e55bc9f2105d9fb5877df982454d8satok return; 1444863fcd62171e55bc9f2105d9fb5877df982454d8satok } 1445863fcd62171e55bc9f2105d9fb5877df982454d8satok try { 1446863fcd62171e55bc9f2105d9fb5877df982454d8satok if (DEBUG) Log.v(TAG, "onViewClicked: " + focusChanged); 1447863fcd62171e55bc9f2105d9fb5877df982454d8satok mCurMethod.viewClicked(focusChanged); 1448863fcd62171e55bc9f2105d9fb5877df982454d8satok } catch (RemoteException e) { 1449863fcd62171e55bc9f2105d9fb5877df982454d8satok Log.w(TAG, "IME died: " + mCurId, e); 1450863fcd62171e55bc9f2105d9fb5877df982454d8satok } 1451863fcd62171e55bc9f2105d9fb5877df982454d8satok } 1452863fcd62171e55bc9f2105d9fb5877df982454d8satok } 1453863fcd62171e55bc9f2105d9fb5877df982454d8satok 1454863fcd62171e55bc9f2105d9fb5877df982454d8satok /** 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the current input method wants to watch the location 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the input editor's cursor in its window. 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isWatchingCursor(View view) { 14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Report the current cursor location in its window. 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void updateCursor(View view, int left, int top, int right, int bottom) { 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkFocus(); 14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 1468b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project if ((mServedView != view && (mServedView == null 1469b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project || !mServedView.checkInputConnectionProxy(view))) 1470b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project || mCurrentTextBoxAttribute == null || mCurMethod == null) { 14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTmpCursorRect.set(left, top, right, bottom); 14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mCursorRect.equals(mTmpCursorRect)) { 14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.d(TAG, "updateCursor"); 14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "CURSOR CHANGE: " + mCurMethod); 14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurMethod.updateCursor(mTmpCursorRect); 14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCursorRect.set(mTmpCursorRect); 14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "IME died: " + mCurId, e); 14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Call {@link InputMethodSession#appPrivateCommand(String, Bundle) 14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * InputMethodSession.appPrivateCommand()} on the current Input Method. 14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param view Optional View that is sending the command, or null if 14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you want to send the command regardless of the view that is attached 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to the input method. 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param action Name of the command to be performed. This <em>must</em> 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * be a scoped name, i.e. prefixed with a package name you own, so that 14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * different developers will not create conflicting commands. 14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param data Any data to include with the command. 14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void sendAppPrivateCommand(View view, String action, Bundle data) { 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkFocus(); 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 1503b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project if ((mServedView != view && (mServedView == null 1504b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project || !mServedView.checkInputConnectionProxy(view))) 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || mCurrentTextBoxAttribute == null || mCurMethod == null) { 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) Log.v(TAG, "APP PRIVATE COMMAND " + action + ": " + data); 15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurMethod.appPrivateCommand(action, data); 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "IME died: " + mCurId, e); 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15162820351489537698ad153c6397edf3270455edc5satok 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15182820351489537698ad153c6397edf3270455edc5satok * Force switch to a new input method component. This can only be called 15192820351489537698ad153c6397edf3270455edc5satok * from an application or a service which has a token of the currently active input method. 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param token Supplies the identifying token given to an input method 15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when it was started, which allows it to perform this operation on 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * itself. 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param id The unique identifier for the new input method to be switched to. 15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setInputMethod(IBinder token, String id) { 15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mService.setInputMethod(token, id); 15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException(e); 15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15322820351489537698ad153c6397edf3270455edc5satok 15332820351489537698ad153c6397edf3270455edc5satok /** 15342820351489537698ad153c6397edf3270455edc5satok * Force switch to a new input method and subtype. This can only be called 15352820351489537698ad153c6397edf3270455edc5satok * from an application or a service which has a token of the currently active input method. 15362820351489537698ad153c6397edf3270455edc5satok * @param token Supplies the identifying token given to an input method 15372820351489537698ad153c6397edf3270455edc5satok * when it was started, which allows it to perform this operation on 15382820351489537698ad153c6397edf3270455edc5satok * itself. 15392820351489537698ad153c6397edf3270455edc5satok * @param id The unique identifier for the new input method to be switched to. 15402820351489537698ad153c6397edf3270455edc5satok * @param subtype The new subtype of the new input method to be switched to. 15412820351489537698ad153c6397edf3270455edc5satok */ 15422820351489537698ad153c6397edf3270455edc5satok public void setInputMethodAndSubtype(IBinder token, String id, InputMethodSubtype subtype) { 15432820351489537698ad153c6397edf3270455edc5satok try { 15442820351489537698ad153c6397edf3270455edc5satok mService.setInputMethodAndSubtype(token, id, subtype); 15452820351489537698ad153c6397edf3270455edc5satok } catch (RemoteException e) { 15462820351489537698ad153c6397edf3270455edc5satok throw new RuntimeException(e); 15472820351489537698ad153c6397edf3270455edc5satok } 15482820351489537698ad153c6397edf3270455edc5satok } 15492820351489537698ad153c6397edf3270455edc5satok 15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Close/hide the input method's soft input area, so the user no longer 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * sees it or can interact with it. This can only be called 15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * from the currently active input method, as validated by the given token. 15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param token Supplies the identifying token given to an input method 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when it was started, which allows it to perform this operation on 15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * itself. 15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param flags Provides additional operating flags. Currently may be 15594df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * 0 or have the {@link #HIDE_IMPLICIT_ONLY}, 15604df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #HIDE_NOT_ALWAYS} bit set. 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void hideSoftInputFromInputMethod(IBinder token, int flags) { 15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mService.hideMySoftInput(token, flags); 15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new RuntimeException(e); 15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 15714df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * Show the input method's soft input area, so the user 15724df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * sees the input method window and can interact with it. 15734df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * This can only be called from the currently active input method, 15744df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * as validated by the given token. 15754df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * 15764df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * @param token Supplies the identifying token given to an input method 15774df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * when it was started, which allows it to perform this operation on 15784df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * itself. 15794df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * @param flags Provides additional operating flags. Currently may be 15804df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * 0 or have the {@link #SHOW_IMPLICIT} or 15814df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project * {@link #SHOW_FORCED} bit set. 15824df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project */ 15834df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public void showSoftInputFromInputMethod(IBinder token, int flags) { 15844df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project try { 15854df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mService.showMySoftInput(token, flags); 15864df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } catch (RemoteException e) { 15874df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project throw new RuntimeException(e); 15884df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 15894df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1592f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown * Dispatches an input event to the IME. 1593f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown * 1594f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown * Returns {@link #DISPATCH_HANDLED} if the event was handled. 1595f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown * Returns {@link #DISPATCH_NOT_HANDLED} if the event was not handled. 1596f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown * Returns {@link #DISPATCH_IN_PROGRESS} if the event is in progress and the 1597f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown * callback will be invoked later. 1598f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown * 15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide 16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1601f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown public int dispatchInputEvent(InputEvent event, Object token, 1602f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown FinishedInputEventCallback callback, Handler handler) { 16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 1604c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (mCurMethod != null) { 1605c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (event instanceof KeyEvent) { 1606c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown KeyEvent keyEvent = (KeyEvent)event; 1607c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (keyEvent.getAction() == KeyEvent.ACTION_DOWN 1608c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown && keyEvent.getKeyCode() == KeyEvent.KEYCODE_SYM 1609c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown && keyEvent.getRepeatCount() == 0) { 1610c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown showInputMethodPickerLocked(); 1611f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown return DISPATCH_HANDLED; 1612c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 161404ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown 1615c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (DEBUG) Log.v(TAG, "DISPATCH INPUT EVENT: " + mCurMethod); 1616f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 1617f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown PendingEvent p = obtainPendingEventLocked( 1618f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown event, token, mCurId, callback, handler); 1619f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown if (mMainLooper.isCurrentThread()) { 1620f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown // Already running on the IMM thread so we can send the event immediately. 1621f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown return sendInputEventOnMainLooperLocked(p); 1622b38070caa5143ab9fd1883e0c7c879533a480bc7Victoria Lease } 1623f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 1624f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown // Post the event to the IMM thread. 1625f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown Message msg = mH.obtainMessage(MSG_SEND_INPUT_EVENT, p); 1626f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown msg.setAsynchronous(true); 1627f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown mH.sendMessage(msg); 1628f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown return DISPATCH_IN_PROGRESS; 1629b38070caa5143ab9fd1883e0c7c879533a480bc7Victoria Lease } 1630b38070caa5143ab9fd1883e0c7c879533a480bc7Victoria Lease } 1631f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown return DISPATCH_NOT_HANDLED; 1632b38070caa5143ab9fd1883e0c7c879533a480bc7Victoria Lease } 1633b38070caa5143ab9fd1883e0c7c879533a480bc7Victoria Lease 1634f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown // Must be called on the main looper 1635f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown void sendInputEventAndReportResultOnMainLooper(PendingEvent p) { 1636f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown final boolean handled; 163704ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown synchronized (mH) { 1638f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown int result = sendInputEventOnMainLooperLocked(p); 1639f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown if (result == DISPATCH_IN_PROGRESS) { 1640f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown return; 16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1642f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 1643f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown handled = (result == DISPATCH_HANDLED); 1644f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown } 1645f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 1646f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown invokeFinishedInputEventCallback(p, handled); 1647f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown } 1648f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 1649f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown // Must be called on the main looper 1650f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown int sendInputEventOnMainLooperLocked(PendingEvent p) { 1651f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown if (mCurChannel != null) { 1652f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown if (mCurSender == null) { 1653f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown mCurSender = new ImeInputEventSender(mCurChannel, mH.getLooper()); 1654f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown } 1655f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 1656f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown final InputEvent event = p.mEvent; 1657f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown final int seq = event.getSequenceNumber(); 1658f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown if (mCurSender.sendInputEvent(seq, event)) { 1659f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown mPendingEvents.put(seq, p); 1660f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown Trace.traceCounter(Trace.TRACE_TAG_INPUT, PENDING_EVENT_COUNTER, 1661f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown mPendingEvents.size()); 1662f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 1663f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown Message msg = mH.obtainMessage(MSG_TIMEOUT_INPUT_EVENT, p); 1664f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown msg.setAsynchronous(true); 1665f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown mH.sendMessageDelayed(msg, INPUT_METHOD_NOT_RESPONDING_TIMEOUT); 1666f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown return DISPATCH_IN_PROGRESS; 1667f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown } 1668f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 1669f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown Log.w(TAG, "Unable to send input event to IME: " 1670f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown + mCurId + " dropping: " + event); 16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1672f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown return DISPATCH_NOT_HANDLED; 16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1674ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 1675f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown void finishedInputEvent(int seq, boolean handled, boolean timeout) { 1676f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown final PendingEvent p; 16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mH) { 1678f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown int index = mPendingEvents.indexOfKey(seq); 1679f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown if (index < 0) { 168004ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown return; // spurious, event already finished or timed out 16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1682f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 1683f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown p = mPendingEvents.valueAt(index); 1684f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown mPendingEvents.removeAt(index); 1685f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown Trace.traceCounter(Trace.TRACE_TAG_INPUT, PENDING_EVENT_COUNTER, mPendingEvents.size()); 1686f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 1687f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown if (timeout) { 1688f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown Log.w(TAG, "Timeout waiting for IME to handle input event after " 1689f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown + INPUT_METHOD_NOT_RESPONDING_TIMEOUT + " ms: " + p.mInputMethodId); 1690f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown } else { 1691f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown mH.removeMessages(MSG_TIMEOUT_INPUT_EVENT, p); 1692f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown } 169304ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown } 1694f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 1695f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown invokeFinishedInputEventCallback(p, handled); 169604ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown } 169704ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown 1698f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown // Assumes the event has already been removed from the queue. 1699f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown void invokeFinishedInputEventCallback(PendingEvent p, boolean handled) { 1700f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown p.mHandled = handled; 1701f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown if (p.mHandler.getLooper().isCurrentThread()) { 1702f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown // Already running on the callback handler thread so we can send the 1703f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown // callback immediately. 1704f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown p.run(); 17054d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown } else { 1706f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown // Post the event to the callback handler thread. 1707f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown // In this case, the callback will be responsible for recycling the event. 1708f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown Message msg = Message.obtain(p.mHandler, p); 1709f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown msg.setAsynchronous(true); 1710f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown msg.sendToTarget(); 17114d656885ed9afec7d758c1862df6f040f5fe16a9Jeff Brown } 171204ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown } 171304ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown 1714f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown private void flushPendingEventsLocked() { 1715f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown mH.removeMessages(MSG_FLUSH_INPUT_EVENT); 1716f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 1717f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown final int count = mPendingEvents.size(); 1718f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown for (int i = 0; i < count; i++) { 1719f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown int seq = mPendingEvents.keyAt(i); 1720f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown Message msg = mH.obtainMessage(MSG_FLUSH_INPUT_EVENT, seq, 0); 1721f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown msg.setAsynchronous(true); 1722f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown msg.sendToTarget(); 172304ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown } 172404ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown } 172504ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown 1726f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown private PendingEvent obtainPendingEventLocked(InputEvent event, Object token, 1727f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown String inputMethodId, FinishedInputEventCallback callback, Handler handler) { 1728f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown PendingEvent p = mPendingEventPool.acquire(); 1729f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown if (p == null) { 173004ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown p = new PendingEvent(); 173104ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown } 1732f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown p.mEvent = event; 1733f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown p.mToken = token; 173404ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown p.mInputMethodId = inputMethodId; 173504ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown p.mCallback = callback; 1736f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown p.mHandler = handler; 173704ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown return p; 173804ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown } 173904ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown 174004ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown private void recyclePendingEventLocked(PendingEvent p) { 1741f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown p.recycle(); 1742f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown mPendingEventPool.release(p); 1743ef17e8710e1d55d1c34dd46a48c4d0eb36b15117Michael Wright } 1744ef17e8710e1d55d1c34dd46a48c4d0eb36b15117Michael Wright 174504ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown public void showInputMethodPicker() { 174604ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown synchronized (mH) { 174704ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown showInputMethodPickerLocked(); 174804ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown } 174904ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown } 175004ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown 175104ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown private void showInputMethodPickerLocked() { 175204ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown try { 175304ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown mService.showInputMethodPickerFromClient(mClient); 175404ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown } catch (RemoteException e) { 175504ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown Log.w(TAG, "IME died: " + mCurId, e); 17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17584df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 1759d4fce2b7f1a861590ce84afcf2f569189251bc59satok /** 1760d4fce2b7f1a861590ce84afcf2f569189251bc59satok * Show the settings for enabling subtypes of the specified input method. 1761d4fce2b7f1a861590ce84afcf2f569189251bc59satok * @param imiId An input method, whose subtypes settings will be shown. If imiId is null, 1762d4fce2b7f1a861590ce84afcf2f569189251bc59satok * subtypes of all input methods will be shown. 1763d4fce2b7f1a861590ce84afcf2f569189251bc59satok */ 1764d4fce2b7f1a861590ce84afcf2f569189251bc59satok public void showInputMethodAndSubtypeEnabler(String imiId) { 176547a44916e2fb33cf4751906386d5f5c903b28d8bsatok synchronized (mH) { 176647a44916e2fb33cf4751906386d5f5c903b28d8bsatok try { 1767d4fce2b7f1a861590ce84afcf2f569189251bc59satok mService.showInputMethodAndSubtypeEnablerFromClient(mClient, imiId); 176847a44916e2fb33cf4751906386d5f5c903b28d8bsatok } catch (RemoteException e) { 176947a44916e2fb33cf4751906386d5f5c903b28d8bsatok Log.w(TAG, "IME died: " + mCurId, e); 177047a44916e2fb33cf4751906386d5f5c903b28d8bsatok } 177147a44916e2fb33cf4751906386d5f5c903b28d8bsatok } 177247a44916e2fb33cf4751906386d5f5c903b28d8bsatok } 177347a44916e2fb33cf4751906386d5f5c903b28d8bsatok 1774d4fce2b7f1a861590ce84afcf2f569189251bc59satok /** 1775d4fce2b7f1a861590ce84afcf2f569189251bc59satok * Returns the current input method subtype. This subtype is one of the subtypes in 1776d4fce2b7f1a861590ce84afcf2f569189251bc59satok * the current input method. This method returns null when the current input method doesn't 1777d4fce2b7f1a861590ce84afcf2f569189251bc59satok * have any input method subtype. 1778d4fce2b7f1a861590ce84afcf2f569189251bc59satok */ 177904d50204705c9da52b218f11972da4e7d7a9cb84satok public InputMethodSubtype getCurrentInputMethodSubtype() { 178004d50204705c9da52b218f11972da4e7d7a9cb84satok synchronized (mH) { 178104d50204705c9da52b218f11972da4e7d7a9cb84satok try { 178204d50204705c9da52b218f11972da4e7d7a9cb84satok return mService.getCurrentInputMethodSubtype(); 178304d50204705c9da52b218f11972da4e7d7a9cb84satok } catch (RemoteException e) { 178404d50204705c9da52b218f11972da4e7d7a9cb84satok Log.w(TAG, "IME died: " + mCurId, e); 178504d50204705c9da52b218f11972da4e7d7a9cb84satok return null; 178604d50204705c9da52b218f11972da4e7d7a9cb84satok } 178704d50204705c9da52b218f11972da4e7d7a9cb84satok } 178804d50204705c9da52b218f11972da4e7d7a9cb84satok } 178904d50204705c9da52b218f11972da4e7d7a9cb84satok 1790d4fce2b7f1a861590ce84afcf2f569189251bc59satok /** 1791d4fce2b7f1a861590ce84afcf2f569189251bc59satok * Switch to a new input method subtype of the current input method. 1792d4fce2b7f1a861590ce84afcf2f569189251bc59satok * @param subtype A new input method subtype to switch. 1793d4fce2b7f1a861590ce84afcf2f569189251bc59satok * @return true if the current subtype was successfully switched. When the specified subtype is 1794d4fce2b7f1a861590ce84afcf2f569189251bc59satok * null, this method returns false. 1795d4fce2b7f1a861590ce84afcf2f569189251bc59satok */ 1796b66d287e3003a0934d5714fbf15e554b3c814906satok public boolean setCurrentInputMethodSubtype(InputMethodSubtype subtype) { 1797b66d287e3003a0934d5714fbf15e554b3c814906satok synchronized (mH) { 1798b66d287e3003a0934d5714fbf15e554b3c814906satok try { 1799b66d287e3003a0934d5714fbf15e554b3c814906satok return mService.setCurrentInputMethodSubtype(subtype); 1800b66d287e3003a0934d5714fbf15e554b3c814906satok } catch (RemoteException e) { 1801b66d287e3003a0934d5714fbf15e554b3c814906satok Log.w(TAG, "IME died: " + mCurId, e); 1802b66d287e3003a0934d5714fbf15e554b3c814906satok return false; 1803b66d287e3003a0934d5714fbf15e554b3c814906satok } 1804b66d287e3003a0934d5714fbf15e554b3c814906satok } 1805b66d287e3003a0934d5714fbf15e554b3c814906satok } 1806b66d287e3003a0934d5714fbf15e554b3c814906satok 1807d4fce2b7f1a861590ce84afcf2f569189251bc59satok /** 1808d4fce2b7f1a861590ce84afcf2f569189251bc59satok * Returns a map of all shortcut input method info and their subtypes. 1809d4fce2b7f1a861590ce84afcf2f569189251bc59satok */ 1810f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok public Map<InputMethodInfo, List<InputMethodSubtype>> getShortcutInputMethodsAndSubtypes() { 18114e4569dab5c75804b01a19b2d6e6101b445c1c68satok synchronized (mH) { 1812f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok HashMap<InputMethodInfo, List<InputMethodSubtype>> ret = 1813f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok new HashMap<InputMethodInfo, List<InputMethodSubtype>>(); 18144e4569dab5c75804b01a19b2d6e6101b445c1c68satok try { 18154e4569dab5c75804b01a19b2d6e6101b445c1c68satok // TODO: We should change the return type from List<Object> to List<Parcelable> 18164e4569dab5c75804b01a19b2d6e6101b445c1c68satok List<Object> info = mService.getShortcutInputMethodsAndSubtypes(); 1817f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok // "info" has imi1, subtype1, subtype2, imi2, subtype2, imi3, subtype3..in the list 1818f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok ArrayList<InputMethodSubtype> subtypes = null; 1819f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok final int N = info.size(); 1820f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok if (info != null && N > 0) { 1821f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok for (int i = 0; i < N; ++i) { 1822f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok Object o = info.get(i); 1823f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok if (o instanceof InputMethodInfo) { 1824f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok if (ret.containsKey(o)) { 1825f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok Log.e(TAG, "IMI list already contains the same InputMethod."); 1826f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok break; 18274e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 1828f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok subtypes = new ArrayList<InputMethodSubtype>(); 1829f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok ret.put((InputMethodInfo)o, subtypes); 1830f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok } else if (subtypes != null && o instanceof InputMethodSubtype) { 1831f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok subtypes.add((InputMethodSubtype)o); 18324e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 18334e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 18344e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 18354e4569dab5c75804b01a19b2d6e6101b445c1c68satok } catch (RemoteException e) { 18364e4569dab5c75804b01a19b2d6e6101b445c1c68satok Log.w(TAG, "IME died: " + mCurId, e); 18374e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 18384e4569dab5c75804b01a19b2d6e6101b445c1c68satok return ret; 18394e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 18404e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 1841f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok 1842d4fce2b7f1a861590ce84afcf2f569189251bc59satok /** 1843d4fce2b7f1a861590ce84afcf2f569189251bc59satok * Force switch to the last used input method and subtype. If the last input method didn't have 1844d4fce2b7f1a861590ce84afcf2f569189251bc59satok * any subtypes, the framework will simply switch to the last input method with no subtype 1845d4fce2b7f1a861590ce84afcf2f569189251bc59satok * specified. 1846d4fce2b7f1a861590ce84afcf2f569189251bc59satok * @param imeToken Supplies the identifying token given to an input method when it was started, 1847d4fce2b7f1a861590ce84afcf2f569189251bc59satok * which allows it to perform this operation on itself. 1848d4fce2b7f1a861590ce84afcf2f569189251bc59satok * @return true if the current input method and subtype was successfully switched to the last 1849d4fce2b7f1a861590ce84afcf2f569189251bc59satok * used input method and subtype. 1850d4fce2b7f1a861590ce84afcf2f569189251bc59satok */ 1851735cf38b8c7f8f91ad087511e44fe79018fa61d6satok public boolean switchToLastInputMethod(IBinder imeToken) { 1852735cf38b8c7f8f91ad087511e44fe79018fa61d6satok synchronized (mH) { 1853735cf38b8c7f8f91ad087511e44fe79018fa61d6satok try { 1854735cf38b8c7f8f91ad087511e44fe79018fa61d6satok return mService.switchToLastInputMethod(imeToken); 1855735cf38b8c7f8f91ad087511e44fe79018fa61d6satok } catch (RemoteException e) { 1856735cf38b8c7f8f91ad087511e44fe79018fa61d6satok Log.w(TAG, "IME died: " + mCurId, e); 1857735cf38b8c7f8f91ad087511e44fe79018fa61d6satok return false; 1858735cf38b8c7f8f91ad087511e44fe79018fa61d6satok } 1859735cf38b8c7f8f91ad087511e44fe79018fa61d6satok } 1860735cf38b8c7f8f91ad087511e44fe79018fa61d6satok } 1861735cf38b8c7f8f91ad087511e44fe79018fa61d6satok 1862e7c6998e0a953ae55487d4fe122739646f9280aasatok /** 1863688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok * Force switch to the next input method and subtype. If there is no IME enabled except 1864688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok * current IME and subtype, do nothing. 1865688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok * @param imeToken Supplies the identifying token given to an input method when it was started, 1866688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok * which allows it to perform this operation on itself. 1867688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok * @param onlyCurrentIme if true, the framework will find the next subtype which 1868688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok * belongs to the current IME 1869688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok * @return true if the current input method and subtype was successfully switched to the next 1870688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok * input method and subtype. 1871688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok */ 1872688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok public boolean switchToNextInputMethod(IBinder imeToken, boolean onlyCurrentIme) { 1873688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok synchronized (mH) { 1874688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok try { 1875688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok return mService.switchToNextInputMethod(imeToken, onlyCurrentIme); 1876688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok } catch (RemoteException e) { 1877688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok Log.w(TAG, "IME died: " + mCurId, e); 1878688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok return false; 1879688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok } 1880688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok } 1881688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok } 1882688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok 1883688bd47fccf1a1373e6287bc49b5b33fad12b7f3satok /** 188415ab6b016c0cabda502c97d248b45f5c617f0428satok * Returns true if the current IME needs to offer the users ways to switch to a next input 188515ab6b016c0cabda502c97d248b45f5c617f0428satok * method (e.g. a globe key.). 188615ab6b016c0cabda502c97d248b45f5c617f0428satok * When an IME sets supportsSwitchingToNextInputMethod and this method returns true, 188715ab6b016c0cabda502c97d248b45f5c617f0428satok * the IME has to offer ways to to invoke {@link #switchToNextInputMethod} accordingly. 188815ab6b016c0cabda502c97d248b45f5c617f0428satok * <p> Note that the system determines the most appropriate next input method 188915ab6b016c0cabda502c97d248b45f5c617f0428satok * and subtype in order to provide the consistent user experience in switching 189015ab6b016c0cabda502c97d248b45f5c617f0428satok * between IMEs and subtypes. 18912b10b52f6c08eb79f48f7388e2f1c69f58a9c96dSatoshi Kataoka * @param imeToken Supplies the identifying token given to an input method when it was started, 18922b10b52f6c08eb79f48f7388e2f1c69f58a9c96dSatoshi Kataoka * which allows it to perform this operation on itself. 18932b10b52f6c08eb79f48f7388e2f1c69f58a9c96dSatoshi Kataoka */ 18942b10b52f6c08eb79f48f7388e2f1c69f58a9c96dSatoshi Kataoka public boolean shouldOfferSwitchingToNextInputMethod(IBinder imeToken) { 18952b10b52f6c08eb79f48f7388e2f1c69f58a9c96dSatoshi Kataoka synchronized (mH) { 18962b10b52f6c08eb79f48f7388e2f1c69f58a9c96dSatoshi Kataoka try { 18972b10b52f6c08eb79f48f7388e2f1c69f58a9c96dSatoshi Kataoka return mService.shouldOfferSwitchingToNextInputMethod(imeToken); 18982b10b52f6c08eb79f48f7388e2f1c69f58a9c96dSatoshi Kataoka } catch (RemoteException e) { 18992b10b52f6c08eb79f48f7388e2f1c69f58a9c96dSatoshi Kataoka Log.w(TAG, "IME died: " + mCurId, e); 19002b10b52f6c08eb79f48f7388e2f1c69f58a9c96dSatoshi Kataoka return false; 19012b10b52f6c08eb79f48f7388e2f1c69f58a9c96dSatoshi Kataoka } 19022b10b52f6c08eb79f48f7388e2f1c69f58a9c96dSatoshi Kataoka } 19032b10b52f6c08eb79f48f7388e2f1c69f58a9c96dSatoshi Kataoka } 19042b10b52f6c08eb79f48f7388e2f1c69f58a9c96dSatoshi Kataoka 19052b10b52f6c08eb79f48f7388e2f1c69f58a9c96dSatoshi Kataoka /** 190691e88122cf28a48fd2e2260da7d3d87dd437227asatok * Set additional input method subtypes. Only a process which shares the same uid with the IME 190791e88122cf28a48fd2e2260da7d3d87dd437227asatok * can add additional input method subtypes to the IME. 190875917b603fe83a87c0fe3902e1a768fc31f8d120satok * Please note that a subtype's status is stored in the system. 190975917b603fe83a87c0fe3902e1a768fc31f8d120satok * For example, enabled subtypes are remembered by the framework even after they are removed 191075917b603fe83a87c0fe3902e1a768fc31f8d120satok * by using this method. If you re-add the same subtypes again, 191175917b603fe83a87c0fe3902e1a768fc31f8d120satok * they will just get enabled. If you want to avoid such conflicts, for instance, you may 191275917b603fe83a87c0fe3902e1a768fc31f8d120satok * want to create a "different" new subtype even with the same locale and mode, 191375917b603fe83a87c0fe3902e1a768fc31f8d120satok * by changing its extra value. The different subtype won't get affected by the stored past 191475917b603fe83a87c0fe3902e1a768fc31f8d120satok * status. (You may want to take a look at {@link InputMethodSubtype#hashCode()} to refer 191575917b603fe83a87c0fe3902e1a768fc31f8d120satok * to the current implementation.) 191691e88122cf28a48fd2e2260da7d3d87dd437227asatok * @param imiId Id of InputMethodInfo which additional input method subtypes will be added to. 1917e7c6998e0a953ae55487d4fe122739646f9280aasatok * @param subtypes subtypes will be added as additional subtypes of the current input method. 1918e7c6998e0a953ae55487d4fe122739646f9280aasatok */ 1919ee5e77cafec2eae70890abdcc1646ed39b06edddsatok public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes) { 1920e7c6998e0a953ae55487d4fe122739646f9280aasatok synchronized (mH) { 1921e7c6998e0a953ae55487d4fe122739646f9280aasatok try { 1922ee5e77cafec2eae70890abdcc1646ed39b06edddsatok mService.setAdditionalInputMethodSubtypes(imiId, subtypes); 1923e7c6998e0a953ae55487d4fe122739646f9280aasatok } catch (RemoteException e) { 1924e7c6998e0a953ae55487d4fe122739646f9280aasatok Log.w(TAG, "IME died: " + mCurId, e); 1925e7c6998e0a953ae55487d4fe122739646f9280aasatok } 1926e7c6998e0a953ae55487d4fe122739646f9280aasatok } 1927e7c6998e0a953ae55487d4fe122739646f9280aasatok } 1928e7c6998e0a953ae55487d4fe122739646f9280aasatok 192968f1b78b7b9139a0e34285ff641a664e664a14b8satok public InputMethodSubtype getLastInputMethodSubtype() { 193068f1b78b7b9139a0e34285ff641a664e664a14b8satok synchronized (mH) { 193168f1b78b7b9139a0e34285ff641a664e664a14b8satok try { 193268f1b78b7b9139a0e34285ff641a664e664a14b8satok return mService.getLastInputMethodSubtype(); 193368f1b78b7b9139a0e34285ff641a664e664a14b8satok } catch (RemoteException e) { 193468f1b78b7b9139a0e34285ff641a664e664a14b8satok Log.w(TAG, "IME died: " + mCurId, e); 193568f1b78b7b9139a0e34285ff641a664e664a14b8satok return null; 193668f1b78b7b9139a0e34285ff641a664e664a14b8satok } 193768f1b78b7b9139a0e34285ff641a664e664a14b8satok } 193868f1b78b7b9139a0e34285ff641a664e664a14b8satok } 193968f1b78b7b9139a0e34285ff641a664e664a14b8satok 19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void doDump(FileDescriptor fd, PrintWriter fout, String[] args) { 19419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Printer p = new PrintWriterPrinter(fout); 19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println("Input method client state for " + this + ":"); 19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mService=" + mService); 19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mMainLooper=" + mMainLooper); 19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mIInputContext=" + mIInputContext); 19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mActive=" + mActive 19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " mHasBeenInactive=" + mHasBeenInactive 19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " mBindSequence=" + mBindSequence 19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " mCurId=" + mCurId); 19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mCurMethod=" + mCurMethod); 19529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mCurRootView=" + mCurRootView); 19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mServedView=" + mServedView); 19547663d80f6b6fd6ca7a736c3802013a09c0abdeb9Dianne Hackborn p.println(" mNextServedView=" + mNextServedView); 19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mServedConnecting=" + mServedConnecting); 19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurrentTextBoxAttribute != null) { 19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mCurrentTextBoxAttribute:"); 19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurrentTextBoxAttribute.dump(p, " "); 19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 19609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mCurrentTextBoxAttribute: null"); 19619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mServedInputConnection=" + mServedInputConnection); 19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mCompletions=" + mCompletions); 19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mCursorRect=" + mCursorRect); 19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mCursorSelStart=" + mCursorSelStart 19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " mCursorSelEnd=" + mCursorSelEnd 19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " mCursorCandStart=" + mCursorCandStart 19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " mCursorCandEnd=" + mCursorCandEnd); 19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 197004ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown 197104ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown /** 197204ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown * Callback that is invoked when an input event that was dispatched to 197304ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown * the IME has been finished. 197404ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown * @hide 197504ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown */ 1976f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown public interface FinishedInputEventCallback { 1977f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown public void onFinishedInputEvent(Object token, boolean handled); 197804ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown } 197904ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown 1980c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown private final class ImeInputEventSender extends InputEventSender { 1981c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown public ImeInputEventSender(InputChannel inputChannel, Looper looper) { 1982c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown super(inputChannel, looper); 1983c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 1984c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 1985c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown @Override 1986c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown public void onInputEventFinished(int seq, boolean handled) { 1987f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown finishedInputEvent(seq, handled, false); 1988c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 1989c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 1990c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 1991f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown private final class PendingEvent implements Runnable { 1992f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown public InputEvent mEvent; 1993f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown public Object mToken; 199404ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown public String mInputMethodId; 1995f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown public FinishedInputEventCallback mCallback; 1996f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown public Handler mHandler; 1997f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown public boolean mHandled; 1998f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 1999f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown public void recycle() { 2000f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown mEvent = null; 2001f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown mToken = null; 2002f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown mInputMethodId = null; 2003f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown mCallback = null; 2004f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown mHandler = null; 2005f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown mHandled = false; 2006f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown } 2007f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 2008f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown @Override 2009f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown public void run() { 2010f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown mCallback.onFinishedInputEvent(mToken, mHandled); 2011f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown 2012f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown synchronized (mH) { 2013f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown recyclePendingEventLocked(this); 2014f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown } 2015f9e989d5f09e72f5c9a59d713521f37d3fdd93ddJeff Brown } 201604ddf3c0508f3d50e6ab82cecc0adc92f52b7803Jeff Brown } 20179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2018