InputMethodManagerService.java revision 7265d9bd6d80c5bedaa6de2b80f6619a301a07c8
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006-2008 The Android Open Source Project 3ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker * 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 7ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * License for the specific language governing permissions and limitations under 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport com.android.internal.content.PackageMonitor; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.os.HandlerCaller; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.view.IInputContext; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.view.IInputMethod; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.view.IInputMethodCallback; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.view.IInputMethodClient; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.view.IInputMethodManager; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.view.IInputMethodSession; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.view.InputBindResult; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 297a0f36bd93ad8a5b8cb3e1fe56dbdb43a0ad3a57Joe Onoratoimport com.android.server.StatusBarManagerService; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.ActivityManagerNative; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.AlertDialog; 35dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackbornimport android.app.PendingIntent; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ComponentName; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.DialogInterface; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.IntentFilter; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.DialogInterface.OnCancelListener; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ServiceConnection; 446da35a0c1205398b7df4776e359f7794584fb128Brandon Ballingerimport android.content.pm.ApplicationInfo; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.ResolveInfo; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.ServiceInfo; 48e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasaniimport android.content.res.Configuration; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.ContentObserver; 52857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onoratoimport android.inputmethodservice.InputMethodService; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IInterface; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Parcel; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 604df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Projectimport android.os.ResultReceiver; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock; 634d733290a112fbe7ca5631ee870094b538f39d80satokimport android.os.SystemProperties; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings; 65e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasaniimport android.provider.Settings.Secure; 66ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokimport android.provider.Settings.SettingNotFoundException; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.EventLog; 69ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokimport android.util.Pair; 708a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.PrintWriterPrinter; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Printer; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IWindowManager; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowManager; 75ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokimport android.view.inputmethod.EditorInfo; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputBinding; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethod; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethodInfo; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethodManager; 80ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokimport android.view.inputmethod.InputMethodSubtype; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter; 85913a8925c07e854a80bf5df87561f290d3a56d61satokimport java.text.Collator; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 887f35c8cc88bea5230f001dd4356f864845d202e5satokimport java.util.HashSet; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 90913a8925c07e854a80bf5df87561f290d3a56d61satokimport java.util.Map; 91913a8925c07e854a80bf5df87561f290d3a56d61satokimport java.util.TreeMap; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class provides a system service that manages input methods. 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class InputMethodManagerService extends IInputMethodManager.Stub 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project implements ServiceConnection, Handler.Callback { 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DEBUG = false; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final String TAG = "InputManagerService"; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int MSG_SHOW_IM_PICKER = 1; 102ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok static final int MSG_SHOW_IM_SUBTYPE_PICKER = 2; 10347a44916e2fb33cf4751906386d5f5c903b28d8bsatok static final int MSG_SHOW_IM_SUBTYPE_ENABLER = 3; 104217f548e79ab1ac3dd9e5be8fb6feaa6dcbe4000satok static final int MSG_SHOW_IM_CONFIG = 4; 105ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int MSG_UNBIND_INPUT = 1000; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int MSG_BIND_INPUT = 1010; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int MSG_SHOW_SOFT_INPUT = 1020; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int MSG_HIDE_SOFT_INPUT = 1030; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int MSG_ATTACH_TOKEN = 1040; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int MSG_CREATE_SESSION = 1050; 112ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int MSG_START_INPUT = 2000; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int MSG_RESTART_INPUT = 2010; 115ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int MSG_UNBIND_METHOD = 3000; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final int MSG_BIND_METHOD = 3010; 118ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final long TIME_TO_RECONNECT = 10*1000; 120ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 121ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private static final int NOT_A_SUBTYPE_ID = -1; 122723a27ef3d7c94fc666abc52e0abd5e8526acb69satok private static final String NOT_A_SUBTYPE_ID_STR = String.valueOf(NOT_A_SUBTYPE_ID); 1234e4569dab5c75804b01a19b2d6e6101b445c1c68satok private static final String SUBTYPE_MODE_KEYBOARD = "keyboard"; 1244e4569dab5c75804b01a19b2d6e6101b445c1c68satok private static final String SUBTYPE_MODE_VOICE = "voice"; 1254e4569dab5c75804b01a19b2d6e6101b445c1c68satok 12657ffc00239edcfe733832771e1429fca20182207satok // TODO: Will formalize this value as API 12757ffc00239edcfe733832771e1429fca20182207satok private static final String SUBTYPE_EXTRAVALUE_EXCLUDE_FROM_LAST_IME = 12857ffc00239edcfe733832771e1429fca20182207satok "excludeFromLastInputMethod"; 12957ffc00239edcfe733832771e1429fca20182207satok 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Context mContext; 1317d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn final Resources mRes; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Handler mHandler; 133d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok final InputMethodSettings mSettings; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final SettingsObserver mSettingsObserver; 135089de88fc2f08d284cf8031aa33cff06011a4162Joe Onorato final StatusBarManagerService mStatusBar; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IWindowManager mIWindowManager; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final HandlerCaller mCaller; 138ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final InputBindResult mNoBinding = new InputBindResult(null, null, -1); 140ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // All known input methods. mMethodMap also serves as the global 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // lock for this class. 143d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok final ArrayList<InputMethodInfo> mMethodList = new ArrayList<InputMethodInfo>(); 144d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok final HashMap<String, InputMethodInfo> mMethodMap = new HashMap<String, InputMethodInfo>(); 145ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class SessionState { 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ClientState client; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IInputMethod method; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IInputMethodSession session; 150ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "SessionState{uid " + client.uid + " pid " + client.pid 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " method " + Integer.toHexString( 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.identityHashCode(method)) 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " session " + Integer.toHexString( 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.identityHashCode(session)) 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "}"; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SessionState(ClientState _client, IInputMethod _method, 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IInputMethodSession _session) { 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project client = _client; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project method = _method; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project session = _session; 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 168ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class ClientState { 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IInputMethodClient client; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IInputContext inputContext; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int uid; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int pid; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final InputBinding binding; 175ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean sessionRequested; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SessionState curSession; 178ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "ClientState{" + Integer.toHexString( 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.identityHashCode(this)) + " uid " + uid 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " pid " + pid + "}"; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ClientState(IInputMethodClient _client, IInputContext _inputContext, 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int _uid, int _pid) { 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project client = _client; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inputContext = _inputContext; 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uid = _uid; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pid = _pid; 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project binding = new InputBinding(null, inputContext.asBinder(), uid, pid); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 195ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final HashMap<IBinder, ClientState> mClients 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project = new HashMap<IBinder, ClientState>(); 198ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 200a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn * Set once the system is ready to run third party code. 201a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn */ 202a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn boolean mSystemReady; 203ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 204a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn /** 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Id of the currently selected input method. 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mCurMethodId; 208ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The current binding sequence number, incremented every time there is 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a new bind performed. 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mCurSeq; 214ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The client that is currently bound to an input method. 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ClientState mCurClient; 219ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 221b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project * The last window token that gained focus. 222b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project */ 223b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project IBinder mCurFocusedWindow; 224ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 225b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project /** 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The input context last provided by the current client. 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IInputContext mCurInputContext; 229ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The attributes last provided by the current client. 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project EditorInfo mCurAttribute; 234ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The input method ID of the input method service that we are currently 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * connected to or in the process of connecting to. 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String mCurId; 240ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 242ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * The current subtype of the current input method. 243ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 244ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private InputMethodSubtype mCurrentSubtype; 245ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 2464e4569dab5c75804b01a19b2d6e6101b445c1c68satok // This list contains the pairs of InputMethodInfo and InputMethodSubtype. 247f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok private final HashMap<InputMethodInfo, ArrayList<InputMethodSubtype>> 248f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok mShortcutInputMethodsAndSubtypes = 249f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok new HashMap<InputMethodInfo, ArrayList<InputMethodSubtype>>(); 250ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 251ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set to true if our ServiceConnection is currently actively bound to 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a service (whether or not we have gotten its IBinder back yet). 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mHaveConnection; 256ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set if the client has asked for the input method to be shown. 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mShowRequested; 261ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set if we were explicitly told to show the input method. 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mShowExplicitlyRequested; 266ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set if we were forced to be shown. 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mShowForced; 271ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set if we last told the input method to show itself. 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mInputShown; 276ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The Intent used to connect to the current input method. 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent mCurIntent; 281ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The token we have made for the currently active input method, to 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * identify it in the future. 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder mCurToken; 287ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If non-null, this is the input method service we are currently connected 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to. 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IInputMethod mCurMethod; 293ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Time that we last initiated a bind to the input method, to determine 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * if we should try to disconnect and reconnect to it. 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long mLastBindTime; 299ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Have we called mCurMethod.bindInput()? 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mBoundToMethod; 304ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Currently enabled session. Only touched by service thread, not 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * protected by a lock. 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SessionState mEnabledSession; 310ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * True if the screen is on. The value is true initially. 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean mScreenOn = true; 315ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 316857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato int mBackDisposition = InputMethodService.BACK_DISPOSITION_DEFAULT; 317857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato int mImeWindowVis; 3184d733290a112fbe7ca5631ee870094b538f39d80satok long mOldSystemSettingsVersion; 319857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AlertDialog.Builder mDialogBuilder; 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AlertDialog mSwitchingDialog; 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputMethodInfo[] mIms; 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence[] mItems; 324ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok int[] mSubtypeIds; 325ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class SettingsObserver extends ContentObserver { 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SettingsObserver(Handler handler) { 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(handler); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver resolver = mContext.getContentResolver(); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resolver.registerContentObserver(Settings.Secure.getUriFor( 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Secure.DEFAULT_INPUT_METHOD), false, this); 332ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok resolver.registerContentObserver(Settings.Secure.getUriFor( 333b6109bb591bc02bf8a2d9d5ca76d69d1961c9b5fsatok Settings.Secure.ENABLED_INPUT_METHODS), false, this); 334b6109bb591bc02bf8a2d9d5ca76d69d1961c9b5fsatok resolver.registerContentObserver(Settings.Secure.getUriFor( 335ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE), false, this); 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 337ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override public void onChange(boolean selfChange) { 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateFromSettingsLocked(); 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 344ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class ScreenOnOffReceiver extends android.content.BroadcastReceiver { 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context context, Intent intent) { 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) { 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mScreenOn = true; 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) { 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mScreenOn = false; 352105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } else if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) { 353105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project hideInputMethodMenu(); 354105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project return; 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3568a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Unexpected intent " + intent); 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Inform the current client of the change in active status 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurClient != null && mCurClient.client != null) { 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurClient.client.setActive(mScreenOn); 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 3658a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Got RemoteException sending 'screen on/off' notification to pid " 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mCurClient.pid + " uid " + mCurClient.uid); 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 370ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 37121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn class MyPackageMonitor extends PackageMonitor { 37221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 37421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 37521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn synchronized (mMethodMap) { 37621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn String curInputMethodId = Settings.Secure.getString(mContext 37721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); 37821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn final int N = mMethodList.size(); 37921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (curInputMethodId != null) { 38021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn for (int i=0; i<N; i++) { 38121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn InputMethodInfo imi = mMethodList.get(i); 38221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (imi.getId().equals(curInputMethodId)) { 38321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn for (String pkg : packages) { 38421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (imi.getPackageName().equals(pkg)) { 38521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (!doit) { 38621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return true; 38721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 388723a27ef3d7c94fc666abc52e0abd5e8526acb69satok resetSelectedInputMethodAndSubtypeLocked(""); 38921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn chooseNewDefaultIMELocked(); 39021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return true; 39121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 39221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 39321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 39421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 39508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 39608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 39721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return false; 39821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 399ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 40021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn @Override 40121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn public void onSomePackagesChanged() { 40221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn synchronized (mMethodMap) { 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputMethodInfo curIm = null; 40421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn String curInputMethodId = Settings.Secure.getString(mContext 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = mMethodList.size(); 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curInputMethodId != null) { 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 40921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn InputMethodInfo imi = mMethodList.get(i); 41021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (imi.getId().equals(curInputMethodId)) { 41121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn curIm = imi; 41221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 41321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn int change = isPackageDisappearing(imi.getPackageName()); 41421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (change == PACKAGE_TEMPORARY_CHANGE 41521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn || change == PACKAGE_PERMANENT_CHANGE) { 4168a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.i(TAG, "Input method uninstalled, disabling: " 41721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn + imi.getComponent()); 41821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn setInputMethodEnabledLocked(imi.getId(), false); 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 422ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 42321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn buildInputMethodListLocked(mMethodList, mMethodMap); 42421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean changed = false; 426ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 42708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (curIm != null) { 42821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn int change = isPackageDisappearing(curIm.getPackageName()); 42921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (change == PACKAGE_TEMPORARY_CHANGE 43021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn || change == PACKAGE_PERMANENT_CHANGE) { 43108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu ServiceInfo si = null; 43208675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu try { 43308675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu si = mContext.getPackageManager().getServiceInfo( 43408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu curIm.getComponent(), 0); 43508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } catch (PackageManager.NameNotFoundException ex) { 43608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 43708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (si == null) { 43808675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu // Uh oh, current input method is no longer around! 43908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu // Pick another one... 4408a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.i(TAG, "Current input method removed: " + curInputMethodId); 441857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mImeWindowVis = 0; 442857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mStatusBar.setImeWindowStatus(mCurToken, mImeWindowVis, 443857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mBackDisposition); 44421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (!chooseNewDefaultIMELocked()) { 44508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu changed = true; 44608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu curIm = null; 4478a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.i(TAG, "Unsetting current input method"); 448723a27ef3d7c94fc666abc52e0abd5e8526acb69satok resetSelectedInputMethodAndSubtypeLocked(""); 44908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 45008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 45108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 45221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 453ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 45421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (curIm == null) { 45521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn // We currently don't have a default input method... is 45621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn // one now available? 45721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn changed = chooseNewDefaultIMELocked(); 45821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 459ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 46021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (changed) { 46121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn updateFromSettingsLocked(); 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 466ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class MethodCallback extends IInputMethodCallback.Stub { 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IInputMethod mMethod; 469ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MethodCallback(IInputMethod method) { 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMethod = method; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 473ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void finishedEvent(int seq, boolean handled) throws RemoteException { 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void sessionCreated(IInputMethodSession session) throws RemoteException { 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project onSessionCreated(mMethod, session); 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 481ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 482089de88fc2f08d284cf8031aa33cff06011a4162Joe Onorato public InputMethodManagerService(Context context, StatusBarManagerService statusBar) { 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 4847d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn mRes = context.getResources(); 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHandler = new Handler(this); 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIWindowManager = IWindowManager.Stub.asInterface( 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ServiceManager.getService(Context.WINDOW_SERVICE)); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCaller = new HandlerCaller(context, new HandlerCaller.Callback() { 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void executeMessage(Message msg) { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handleMessage(msg); 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }); 4934d733290a112fbe7ca5631ee870094b538f39d80satok // Initialize the system settings version to undefined. 4944d733290a112fbe7ca5631ee870094b538f39d80satok mOldSystemSettingsVersion = -1; 495ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 49621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn (new MyPackageMonitor()).register(mContext, true); 497ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IntentFilter screenOnOffFilt = new IntentFilter(); 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project screenOnOffFilt.addAction(Intent.ACTION_SCREEN_ON); 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project screenOnOffFilt.addAction(Intent.ACTION_SCREEN_OFF); 501105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project screenOnOffFilt.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.registerReceiver(new ScreenOnOffReceiver(), screenOnOffFilt); 503ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 504913a8925c07e854a80bf5df87561f290d3a56d61satok mStatusBar = statusBar; 505913a8925c07e854a80bf5df87561f290d3a56d61satok statusBar.setIconVisibility("ime", false); 506913a8925c07e854a80bf5df87561f290d3a56d61satok 507d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // mSettings should be created before buildInputMethodListLocked 508df31ae6a3011d47421a6ac10021f9649dc34a156satok mSettings = new InputMethodSettings( 509df31ae6a3011d47421a6ac10021f9649dc34a156satok mRes, context.getContentResolver(), mMethodMap, mMethodList); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buildInputMethodListLocked(mMethodList, mMethodMap); 511d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok mSettings.enableAllIMEsIfThereIsNoEnabledIME(); 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 513d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok if (TextUtils.isEmpty(Settings.Secure.getString( 514d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD))) { 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputMethodInfo defIm = null; 516d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok for (InputMethodInfo imi: mMethodList) { 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (defIm == null && imi.getIsDefaultResourceId() != 0) { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 519d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok Resources res = context.createPackageContext( 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project imi.getPackageName(), 0).getResources(); 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (res.getBoolean(imi.getIsDefaultResourceId())) { 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project defIm = imi; 5238a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.i(TAG, "Selected default: " + imi.getId()); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PackageManager.NameNotFoundException ex) { 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException ex) { 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 530d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok if (defIm == null && mMethodList.size() > 0) { 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project defIm = mMethodList.get(0); 5328a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.i(TAG, "No default found, using " + defIm.getId()); 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (defIm != null) { 535723a27ef3d7c94fc666abc52e0abd5e8526acb69satok setSelectedInputMethodAndSubtypeLocked(defIm, NOT_A_SUBTYPE_ID, false); 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 538ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSettingsObserver = new SettingsObserver(mHandler); 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateFromSettingsLocked(); 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws RemoteException { 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return super.onTransact(code, data, reply, flags); 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RuntimeException e) { 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The input method manager only throws security exceptions, so let's 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // log all others. 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!(e instanceof SecurityException)) { 5528a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "Input Method Manager Crash", e); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void systemReady() { 559a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn synchronized (mMethodMap) { 560a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn if (!mSystemReady) { 561a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn mSystemReady = true; 562cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn try { 563cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn startInputInnerLocked(); 564cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn } catch (RuntimeException e) { 5658a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Unexpected exception", e); 566cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn } 567a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn } 568a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn } 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 570ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<InputMethodInfo> getInputMethodList() { 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new ArrayList<InputMethodInfo>(mMethodList); 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<InputMethodInfo> getEnabledInputMethodList() { 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 579d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok return mSettings.getEnabledInputMethodListLocked(); 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 583bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok private HashMap<InputMethodInfo, List<InputMethodSubtype>> 584bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked() { 585bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok HashMap<InputMethodInfo, List<InputMethodSubtype>> enabledInputMethodAndSubtypes = 586bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok new HashMap<InputMethodInfo, List<InputMethodSubtype>>(); 587bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok for (InputMethodInfo imi: getEnabledInputMethodList()) { 588bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok enabledInputMethodAndSubtypes.put( 589bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok imi, getEnabledInputMethodSubtypeListLocked(imi, true)); 590bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok } 591bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok return enabledInputMethodAndSubtypes; 592bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok } 593bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok 594bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok public List<InputMethodSubtype> getEnabledInputMethodSubtypeListLocked(InputMethodInfo imi, 595bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok boolean allowsImplicitlySelectedSubtypes) { 596bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok if (imi == null && mCurMethodId != null) { 597bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok imi = mMethodMap.get(mCurMethodId); 598bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok } 5997265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok List<InputMethodSubtype> enabledSubtypes = 600bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok mSettings.getEnabledInputMethodSubtypeListLocked(imi); 6017265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok if (allowsImplicitlySelectedSubtypes && enabledSubtypes.isEmpty()) { 6027265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok enabledSubtypes = getApplicableSubtypesLocked(mRes, getSubtypes(imi)); 603bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok } 6047265d9bd6d80c5bedaa6de2b80f6619a301a07c8satok return InputMethodSubtype.sort(mContext, 0, imi, enabledSubtypes); 605bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok } 606bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok 60716331c8a1d33defccc5cbb18694def79196c921bsatok public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(InputMethodInfo imi, 60816331c8a1d33defccc5cbb18694def79196c921bsatok boolean allowsImplicitlySelectedSubtypes) { 60967ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok synchronized (mMethodMap) { 610bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok return getEnabledInputMethodSubtypeListLocked(imi, allowsImplicitlySelectedSubtypes); 61167ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok } 61267ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok } 61367ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addClient(IInputMethodClient client, 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IInputContext inputContext, int uid, int pid) { 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClients.put(client.asBinder(), new ClientState(client, 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inputContext, uid, pid)); 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 621ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeClient(IInputMethodClient client) { 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mClients.remove(client.asBinder()); 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 627ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void executeOrSendMessage(IInterface target, Message msg) { 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (target.asBinder() instanceof Binder) { 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCaller.sendMessage(msg); 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project handleMessage(msg); 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project msg.recycle(); 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 636ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 637b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project void unbindCurrentClientLocked() { 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurClient != null) { 6398a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "unbindCurrentInputLocked: client = " 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mCurClient.client.asBinder()); 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mBoundToMethod) { 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBoundToMethod = false; 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurMethod != null) { 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project executeOrSendMessage(mCurMethod, mCaller.obtainMessageO( 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MSG_UNBIND_INPUT, mCurMethod)); 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO( 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MSG_UNBIND_METHOD, mCurSeq, mCurClient.client)); 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurClient.sessionRequested = false; 651ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Call setActive(false) on the old client 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurClient.client.setActive(false); 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6568a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Got RemoteException sending setActive(false) notification to pid " 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mCurClient.pid + " uid " + mCurClient.uid); 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurClient = null; 660ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 661105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project hideInputMethodMenuLocked(); 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 664ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int getImeShowFlags() { 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int flags = 0; 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mShowForced) { 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags |= InputMethod.SHOW_FORCED 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project | InputMethod.SHOW_EXPLICIT; 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mShowExplicitlyRequested) { 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags |= InputMethod.SHOW_EXPLICIT; 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return flags; 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 675ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int getAppShowFlags() { 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int flags = 0; 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mShowForced) { 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags |= InputMethodManager.SHOW_FORCED; 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!mShowExplicitlyRequested) { 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags |= InputMethodManager.SHOW_IMPLICIT; 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return flags; 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 685ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputBindResult attachNewInputLocked(boolean initial, boolean needResult) { 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mBoundToMethod) { 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO( 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MSG_BIND_INPUT, mCurMethod, mCurClient.binding)); 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBoundToMethod = true; 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final SessionState session = mCurClient.curSession; 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (initial) { 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project executeOrSendMessage(session.method, mCaller.obtainMessageOOO( 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MSG_START_INPUT, session, mCurInputContext, mCurAttribute)); 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project executeOrSendMessage(session.method, mCaller.obtainMessageOOO( 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MSG_RESTART_INPUT, session, mCurInputContext, mCurAttribute)); 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mShowRequested) { 7018a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Attach new input asks to show input"); 7024df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project showCurrentInputLocked(getAppShowFlags(), null); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return needResult 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ? new InputBindResult(session.session, mCurId, mCurSeq) 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : null; 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 708ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputBindResult startInputLocked(IInputMethodClient client, 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IInputContext inputContext, EditorInfo attribute, 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean initial, boolean needResult) { 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If no method is currently selected, do nothing. 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurMethodId == null) { 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mNoBinding; 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 716ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ClientState cs = mClients.get(client.asBinder()); 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cs == null) { 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("unknown client " 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + client.asBinder()); 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 722ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mIWindowManager.inputMethodClientHasFocus(cs.client)) { 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check with the window manager to make sure this client actually 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // has a window with focus. If not, reject. This is thread safe 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // because if the focus changes some time before or after, the 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // next client receiving focus that has any interest in input will 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // be calling through here after that change happens. 7308a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Starting input on non-focused client " + cs.client 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " (uid=" + cs.uid + " pid=" + cs.pid + ")"); 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 736ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurClient != cs) { 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the client is changing, we need to switch over to the new 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // one. 740b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project unbindCurrentClientLocked(); 7418a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "switching to client: client = " 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + cs.client.asBinder()); 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the screen is on, inform the new client it is active 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mScreenOn) { 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cs.client.setActive(mScreenOn); 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 7498a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Got RemoteException sending setActive notification to pid " 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + cs.pid + " uid " + cs.uid); 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 754ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Bump up the sequence for this client and attach it. 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurSeq++; 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurSeq <= 0) mCurSeq = 1; 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurClient = cs; 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurInputContext = inputContext; 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurAttribute = attribute; 761ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check if the input method is changing. 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurId != null && mCurId.equals(mCurMethodId)) { 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (cs.curSession != null) { 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Fast case: if we are already connected to the input method, 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // then just return it. 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return attachNewInputLocked(initial, needResult); 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mHaveConnection) { 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurMethod != null) { 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!cs.sessionRequested) { 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cs.sessionRequested = true; 7738a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Creating new session for client " + cs); 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO( 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MSG_CREATE_SESSION, mCurMethod, 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new MethodCallback(mCurMethod))); 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Return to client, and we will get back with it when 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we have had a session made for it. 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new InputBindResult(null, mCurId, mCurSeq); 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (SystemClock.uptimeMillis() 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project < (mLastBindTime+TIME_TO_RECONNECT)) { 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // In this case we have connected to the service, but 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // don't yet have its interface. If it hasn't been too 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // long since we did the connection, we'll return to 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the client and wait to get the service interface so 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we can report back. If it has been too long, we want 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to fall through so we can try a disconnect/reconnect 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to see if we can get back in touch with the service. 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new InputBindResult(null, mCurId, mCurSeq); 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 792ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME, 793ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker mCurMethodId, SystemClock.uptimeMillis()-mLastBindTime, 0); 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 797ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 798a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn return startInputInnerLocked(); 799a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn } 800ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 801a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn InputBindResult startInputInnerLocked() { 802a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn if (mCurMethodId == null) { 803a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn return mNoBinding; 804a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn } 805ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 806a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn if (!mSystemReady) { 807a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn // If the system is not yet ready, we shouldn't be running third 808a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn // party code. 809cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn return new InputBindResult(null, mCurMethodId, mCurSeq); 810a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn } 811ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputMethodInfo info = mMethodMap.get(mCurMethodId); 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (info == null) { 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Unknown id: " + mCurMethodId); 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 816ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 817b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project unbindCurrentMethodLocked(false); 818ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurIntent = new Intent(InputMethod.SERVICE_INTERFACE); 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurIntent.setComponent(info.getComponent()); 821dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn mCurIntent.putExtra(Intent.EXTRA_CLIENT_LABEL, 822dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn com.android.internal.R.string.input_method_binding_label); 823dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn mCurIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity( 824dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0)); 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.bindService(mCurIntent, this, Context.BIND_AUTO_CREATE)) { 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastBindTime = SystemClock.uptimeMillis(); 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mHaveConnection = true; 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurId = info.getId(); 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurToken = new Binder(); 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8318a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Adding window token: " + mCurToken); 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIWindowManager.addWindowToken(mCurToken, 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.TYPE_INPUT_METHOD); 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new InputBindResult(null, mCurId, mCurSeq); 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurIntent = null; 8398a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Failure connecting to input method service: " 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + mCurIntent); 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 844ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public InputBindResult startInput(IInputMethodClient client, 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IInputContext inputContext, EditorInfo attribute, 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean initial, boolean needResult) { 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long ident = Binder.clearCallingIdentity(); 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return startInputLocked(client, inputContext, attribute, 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project initial, needResult); 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Binder.restoreCallingIdentity(ident); 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 858ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void finishInput(IInputMethodClient client) { 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 861ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onServiceConnected(ComponentName name, IBinder service) { 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurIntent != null && name.equals(mCurIntent.getComponent())) { 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurMethod = IInputMethod.Stub.asInterface(service); 866cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn if (mCurToken == null) { 8678a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Service connected without a token!"); 868cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn unbindCurrentMethodLocked(false); 869cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn return; 870cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn } 8718a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Initiating attach with token: " + mCurToken); 872cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO( 873cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn MSG_ATTACH_TOKEN, mCurMethod, mCurToken)); 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurClient != null) { 8758a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Creating first session while with client " 876cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn + mCurClient); 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO( 878cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn MSG_CREATE_SESSION, mCurMethod, 879cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn new MethodCallback(mCurMethod))); 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void onSessionCreated(IInputMethod method, IInputMethodSession session) { 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurMethod != null && method != null 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && mCurMethod.asBinder() == method.asBinder()) { 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurClient != null) { 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurClient.curSession = new SessionState(mCurClient, 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project method, session); 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurClient.sessionRequested = false; 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputBindResult res = attachNewInputLocked(true, true); 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (res.method != null) { 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project executeOrSendMessage(mCurClient.client, mCaller.obtainMessageOO( 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MSG_BIND_METHOD, mCurClient.client, res)); 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 902ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 903b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project void unbindCurrentMethodLocked(boolean reportToClient) { 904b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project if (mHaveConnection) { 905b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project mContext.unbindService(this); 906b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project mHaveConnection = false; 907b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project } 908ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 909b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project if (mCurToken != null) { 910b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project try { 9118a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Removing window token: " + mCurToken); 912b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project mIWindowManager.removeWindowToken(mCurToken); 913b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project } catch (RemoteException e) { 914b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project } 915b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project mCurToken = null; 916b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project } 917ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 918105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mCurId = null; 919b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project clearCurMethodLocked(); 920ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 921b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project if (reportToClient && mCurClient != null) { 922b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO( 923b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project MSG_UNBIND_METHOD, mCurSeq, mCurClient.client)); 924b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project } 925b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project } 926b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project 9270c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor private void finishSession(SessionState sessionState) { 9280c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor if (sessionState != null && sessionState.session != null) { 9290c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor try { 9300c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor sessionState.session.finishSession(); 9310c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor } catch (RemoteException e) { 9329d0f6dfdc1ac0b9374acf51572f273e9c9bbc9f9Jean-Baptiste Queru Slog.w(TAG, "Session failed to close due to remote exception", e); 9330c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor } 9340c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor } 9350c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor } 936ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 937b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project void clearCurMethodLocked() { 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurMethod != null) { 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (ClientState cs : mClients.values()) { 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cs.sessionRequested = false; 9410c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor finishSession(cs.curSession); 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cs.curSession = null; 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9440c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor 9450c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor finishSession(mEnabledSession); 9460c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor mEnabledSession = null; 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCurMethod = null; 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9490cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato mStatusBar.setIconVisibility("ime", false); 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 951ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onServiceDisconnected(ComponentName name) { 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 9548a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Service disconnected: " + name 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " mCurIntent=" + mCurIntent); 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurMethod != null && mCurIntent != null 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && name.equals(mCurIntent.getComponent())) { 958b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project clearCurMethodLocked(); 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We consider this to be a new bind attempt, since the system 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // should now try to restart the service for us. 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastBindTime = SystemClock.uptimeMillis(); 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShowRequested = mInputShown; 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInputShown = false; 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurClient != null) { 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO( 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MSG_UNBIND_METHOD, mCurSeq, mCurClient.client)); 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void updateStatusIcon(IBinder token, String packageName, int iconId) { 973cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn int uid = Binder.getCallingUid(); 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long ident = Binder.clearCallingIdentity(); 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (token == null || mCurToken != token) { 977cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn Slog.w(TAG, "Ignoring setInputMethod of uid " + uid + " token: " + token); 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 980ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (iconId == 0) { 9838a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.d(TAG, "hide the small icon for the input method"); 9840cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato mStatusBar.setIconVisibility("ime", false); 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (packageName != null) { 9868a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.d(TAG, "show a small icon for the input method"); 9870cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato mStatusBar.setIcon("ime", packageName, iconId, 0); 9880cbda99f8721ad9b03ada04d2637fb75a2a0fecaJoe Onorato mStatusBar.setIconVisibility("ime", true); 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Binder.restoreCallingIdentity(ident); 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 996857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato public void setImeWindowStatus(IBinder token, int vis, int backDisposition) { 99706487a58be22b100daf3f950b9a1d25c3ea42aa2satok int uid = Binder.getCallingUid(); 99806487a58be22b100daf3f950b9a1d25c3ea42aa2satok long ident = Binder.clearCallingIdentity(); 99906487a58be22b100daf3f950b9a1d25c3ea42aa2satok try { 100006487a58be22b100daf3f950b9a1d25c3ea42aa2satok if (token == null || mCurToken != token) { 1001857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato Slog.w(TAG, "Ignoring setImeWindowStatus of uid " + uid + " token: " + token); 100206487a58be22b100daf3f950b9a1d25c3ea42aa2satok return; 100306487a58be22b100daf3f950b9a1d25c3ea42aa2satok } 100406487a58be22b100daf3f950b9a1d25c3ea42aa2satok 100506487a58be22b100daf3f950b9a1d25c3ea42aa2satok synchronized (mMethodMap) { 1006857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mImeWindowVis = vis; 1007857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mBackDisposition = backDisposition; 1008857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mStatusBar.setImeWindowStatus(token, vis, backDisposition); 100906487a58be22b100daf3f950b9a1d25c3ea42aa2satok } 101006487a58be22b100daf3f950b9a1d25c3ea42aa2satok } finally { 101106487a58be22b100daf3f950b9a1d25c3ea42aa2satok Binder.restoreCallingIdentity(ident); 101206487a58be22b100daf3f950b9a1d25c3ea42aa2satok } 101306487a58be22b100daf3f950b9a1d25c3ea42aa2satok } 101406487a58be22b100daf3f950b9a1d25c3ea42aa2satok 10154d733290a112fbe7ca5631ee870094b538f39d80satok // TODO: Investigate and fix why are settings changes getting processed before the settings seq 10164d733290a112fbe7ca5631ee870094b538f39d80satok // number is updated? 10174d733290a112fbe7ca5631ee870094b538f39d80satok // TODO: Change this stuff to not rely on modifying settings for normal user interactions. 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void updateFromSettingsLocked() { 10194d733290a112fbe7ca5631ee870094b538f39d80satok long newSystemSettingsVersion = getSystemSettingsVersion(); 10204d733290a112fbe7ca5631ee870094b538f39d80satok // This is a workaround to avoid a situation that old cached value in Settings.Secure 10214d733290a112fbe7ca5631ee870094b538f39d80satok // will be handled. 10224d733290a112fbe7ca5631ee870094b538f39d80satok if (newSystemSettingsVersion == mOldSystemSettingsVersion) return; 10234d733290a112fbe7ca5631ee870094b538f39d80satok 1024b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project // We are assuming that whoever is changing DEFAULT_INPUT_METHOD and 1025b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project // ENABLED_INPUT_METHODS is taking care of keeping them correctly in 1026b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project // sync, so we will never have a DEFAULT_INPUT_METHOD that is not 1027b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project // enabled. 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String id = Settings.Secure.getString(mContext.getContentResolver(), 1029ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok Settings.Secure.DEFAULT_INPUT_METHOD); 103003eb319a3a7fe6fe9ab9eba6fc1f727285850906satok // There is no input method selected, try to choose new applicable input method. 103103eb319a3a7fe6fe9ab9eba6fc1f727285850906satok if (TextUtils.isEmpty(id) && chooseNewDefaultIMELocked()) { 103203eb319a3a7fe6fe9ab9eba6fc1f727285850906satok id = Settings.Secure.getString(mContext.getContentResolver(), 103303eb319a3a7fe6fe9ab9eba6fc1f727285850906satok Settings.Secure.DEFAULT_INPUT_METHOD); 103403eb319a3a7fe6fe9ab9eba6fc1f727285850906satok } 103503eb319a3a7fe6fe9ab9eba6fc1f727285850906satok if (!TextUtils.isEmpty(id)) { 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1037ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok setInputMethodLocked(id, getSelectedInputMethodSubtypeId(id)); 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IllegalArgumentException e) { 10398a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Unknown input method from prefs: " + id, e); 1040105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mCurMethodId = null; 1041b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project unbindCurrentMethodLocked(true); 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1043f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok mShortcutInputMethodsAndSubtypes.clear(); 1044b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project } else { 1045b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project // There is no longer an input method set, so stop any current one. 1046105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mCurMethodId = null; 1047b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project unbindCurrentMethodLocked(true); 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1050ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1051ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /* package */ void setInputMethodLocked(String id, int subtypeId) { 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputMethodInfo info = mMethodMap.get(id); 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (info == null) { 1054913a8925c07e854a80bf5df87561f290d3a56d61satok throw new IllegalArgumentException("Unknown id: " + id); 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1056ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id.equals(mCurMethodId)) { 1058cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok InputMethodSubtype subtype = null; 1059586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa if (subtypeId >= 0 && subtypeId < info.getSubtypeCount()) { 1060586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa subtype = info.getSubtypeAt(subtypeId); 1061cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok } 1062cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok if (subtype != mCurrentSubtype) { 1063cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok synchronized (mMethodMap) { 1064ca83021e3555e8b2bd07ded7885dc44053cd1a25satok if (subtype != null) { 1065ca83021e3555e8b2bd07ded7885dc44053cd1a25satok setSelectedInputMethodAndSubtypeLocked(info, subtypeId, true); 1066ca83021e3555e8b2bd07ded7885dc44053cd1a25satok } 1067cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok if (mCurMethod != null) { 1068cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok try { 1069e40dea0d06ec1c04db80191fd2965363b4fac781satok final Configuration conf = mRes.getConfiguration(); 1070e40dea0d06ec1c04db80191fd2965363b4fac781satok final boolean haveHardKeyboard = conf.keyboard 1071e40dea0d06ec1c04db80191fd2965363b4fac781satok != Configuration.KEYBOARD_NOKEYS; 1072e40dea0d06ec1c04db80191fd2965363b4fac781satok final boolean hardKeyShown = haveHardKeyboard 10738710e76a897cd546a79ee4338a4147eeb9f3e068Ken Wakasa && conf.hardKeyboardHidden 10748710e76a897cd546a79ee4338a4147eeb9f3e068Ken Wakasa != Configuration.HARDKEYBOARDHIDDEN_YES; 1075e40dea0d06ec1c04db80191fd2965363b4fac781satok mImeWindowVis = (mInputShown || hardKeyShown) ? ( 1076e40dea0d06ec1c04db80191fd2965363b4fac781satok InputMethodService.IME_ACTIVE | InputMethodService.IME_VISIBLE) 1077e40dea0d06ec1c04db80191fd2965363b4fac781satok : 0; 1078857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mStatusBar.setImeWindowStatus(mCurToken, mImeWindowVis, 1079857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mBackDisposition); 1080cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok // If subtype is null, try to find the most applicable one from 1081cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok // getCurrentInputMethodSubtype. 1082cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok if (subtype == null) { 1083cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok subtype = getCurrentInputMethodSubtype(); 1084ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 1085cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok mCurMethod.changeInputMethodSubtype(subtype); 1086cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok } catch (RemoteException e) { 1087cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok return; 1088ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 1089ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 1090ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 1091ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1094ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long ident = Binder.clearCallingIdentity(); 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1097ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok // Set a subtype to this input method. 1098ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok // subtypeId the name of a subtype which will be set. 1099723a27ef3d7c94fc666abc52e0abd5e8526acb69satok setSelectedInputMethodAndSubtypeLocked(info, subtypeId, false); 1100723a27ef3d7c94fc666abc52e0abd5e8526acb69satok // mCurMethodId should be updated after setSelectedInputMethodAndSubtypeLocked() 1101723a27ef3d7c94fc666abc52e0abd5e8526acb69satok // because mCurMethodId is stored as a history in 1102723a27ef3d7c94fc666abc52e0abd5e8526acb69satok // setSelectedInputMethodAndSubtypeLocked(). 1103723a27ef3d7c94fc666abc52e0abd5e8526acb69satok mCurMethodId = id; 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ActivityManagerNative.isSystemReady()) { 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(Intent.ACTION_INPUT_METHOD_CHANGED); 11071c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra("input_method_id", id); 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1111b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project unbindCurrentClientLocked(); 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Binder.restoreCallingIdentity(ident); 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1116ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 11174df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public boolean showSoftInput(IInputMethodClient client, int flags, 11184df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project ResultReceiver resultReceiver) { 1119cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn int uid = Binder.getCallingUid(); 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long ident = Binder.clearCallingIdentity(); 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurClient == null || client == null 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || mCurClient.client.asBinder() != client.asBinder()) { 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We need to check if this is the current client with 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // focus in the window manager, to allow this call to 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // be made before input is started in it. 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mIWindowManager.inputMethodClientHasFocus(client)) { 1130cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn Slog.w(TAG, "Ignoring showSoftInput of uid " + uid + ": " + client); 11314df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return false; 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 11344df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return false; 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1137ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 11388a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Client requesting input be shown"); 11394df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return showCurrentInputLocked(flags, resultReceiver); 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Binder.restoreCallingIdentity(ident); 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1145ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 11464df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project boolean showCurrentInputLocked(int flags, ResultReceiver resultReceiver) { 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShowRequested = true; 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags&InputMethodManager.SHOW_IMPLICIT) == 0) { 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShowExplicitlyRequested = true; 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags&InputMethodManager.SHOW_FORCED) != 0) { 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShowExplicitlyRequested = true; 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShowForced = true; 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1155ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1156cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn if (!mSystemReady) { 1157cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn return false; 1158cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn } 1159ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 11604df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project boolean res = false; 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurMethod != null) { 11624df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOO( 11634df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project MSG_SHOW_SOFT_INPUT, getImeShowFlags(), mCurMethod, 11644df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project resultReceiver)); 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInputShown = true; 11664df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project res = true; 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mHaveConnection && SystemClock.uptimeMillis() 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project < (mLastBindTime+TIME_TO_RECONNECT)) { 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The client has asked to have the input method shown, but 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we have been sitting here too long with a connection to the 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // service and no interface received, so let's disconnect/connect 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to try to prod things along. 1173ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME, mCurMethodId, 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SystemClock.uptimeMillis()-mLastBindTime,1); 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.unbindService(this); 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.bindService(mCurIntent, this, Context.BIND_AUTO_CREATE); 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1178ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 11794df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return res; 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1181ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 11824df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public boolean hideSoftInput(IInputMethodClient client, int flags, 11834df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project ResultReceiver resultReceiver) { 1184cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn int uid = Binder.getCallingUid(); 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long ident = Binder.clearCallingIdentity(); 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurClient == null || client == null 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || mCurClient.client.asBinder() != client.asBinder()) { 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We need to check if this is the current client with 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // focus in the window manager, to allow this call to 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // be made before input is started in it. 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mIWindowManager.inputMethodClientHasFocus(client)) { 1195cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn if (DEBUG) Slog.w(TAG, "Ignoring hideSoftInput of uid " 1196cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn + uid + ": " + client); 1197857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mImeWindowVis = 0; 1198857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mStatusBar.setImeWindowStatus(mCurToken, mImeWindowVis, 1199857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mBackDisposition); 12004df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return false; 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 1203857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mImeWindowVis = 0; 1204857fd9b8562c29913e03ed29288bd1802d37dc60Joe Onorato mStatusBar.setImeWindowStatus(mCurToken, mImeWindowVis, mBackDisposition); 12054df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return false; 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1208ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 12098a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Client requesting input be hidden"); 12104df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return hideCurrentInputLocked(flags, resultReceiver); 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Binder.restoreCallingIdentity(ident); 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1216ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 12174df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project boolean hideCurrentInputLocked(int flags, ResultReceiver resultReceiver) { 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags&InputMethodManager.HIDE_IMPLICIT_ONLY) != 0 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (mShowExplicitlyRequested || mShowForced)) { 12208a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Not hiding: explicit show not cancelled by non-explicit hide"); 12224df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return false; 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mShowForced && (flags&InputMethodManager.HIDE_NOT_ALWAYS) != 0) { 12258a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Not hiding: forced show not cancelled by not-always hide"); 12274df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return false; 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12294df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project boolean res; 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mInputShown && mCurMethod != null) { 12314df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO( 12324df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project MSG_HIDE_SOFT_INPUT, mCurMethod, resultReceiver)); 12334df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project res = true; 12344df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } else { 12354df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project res = false; 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInputShown = false; 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShowRequested = false; 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShowExplicitlyRequested = false; 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShowForced = false; 12414df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return res; 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1243ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1244b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project public void windowGainedFocus(IInputMethodClient client, IBinder windowToken, 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean viewHasFocus, boolean isTextEditor, int softInputMode, 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean first, int windowFlags) { 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long ident = Binder.clearCallingIdentity(); 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 12508a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "windowGainedFocus: " + client.asBinder() 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " viewHasFocus=" + viewHasFocus 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " isTextEditor=" + isTextEditor 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " softInputMode=#" + Integer.toHexString(softInputMode) 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " first=" + first + " flags=#" 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Integer.toHexString(windowFlags)); 1256ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurClient == null || client == null 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || mCurClient.client.asBinder() != client.asBinder()) { 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We need to check if this is the current client with 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // focus in the window manager, to allow this call to 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // be made before input is started in it. 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mIWindowManager.inputMethodClientHasFocus(client)) { 12648a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Client not active, ignoring focus gain of: " + client); 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1270ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1271b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project if (mCurFocusedWindow == windowToken) { 12728a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client); 1273b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project return; 1274b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project } 1275b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project mCurFocusedWindow = windowToken; 1276ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 12777d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn // Should we auto-show the IME even if the caller has not 12787d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn // specified what should be done with it? 12797d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn // We only do this automatically if the window can resize 12807d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn // to accommodate the IME (so what the user sees will give 12817d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn // them good context without input information being obscured 12827d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn // by the IME) or if running on a large screen where there 12837d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn // is more room for the target window + IME. 12847d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn final boolean doAutoShow = 12857d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn (softInputMode & WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST) 12867d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE 12877d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn || mRes.getConfiguration().isLayoutSizeAtLeast( 12887d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn Configuration.SCREENLAYOUT_SIZE_LARGE); 12897d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (softInputMode&WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE) { 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED: 12927d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn if (!isTextEditor || !doAutoShow) { 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (WindowManager.LayoutParams.mayUseInputMethod(windowFlags)) { 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // There is no focus view, and this window will 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // be behind any soft input window, so hide the 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // soft input window if it is shown. 12978a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Unspecified window will hide input"); 12984df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project hideCurrentInputLocked(InputMethodManager.HIDE_NOT_ALWAYS, null); 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13007d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn } else if (isTextEditor && doAutoShow && (softInputMode & 13017d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) { 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // There is a focus view, and we are navigating forward 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // into the window, so show the input window for the user. 13047d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn // We only do this automatically if the window an resize 13057d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn // to accomodate the IME (so what the user sees will give 13067d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn // them good context without input information being obscured 13077d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn // by the IME) or if running on a large screen where there 13087d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn // is more room for the target window + IME. 13098a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Unspecified window will show input"); 13104df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null); 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED: 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Do nothing. 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN: 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((softInputMode & 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) { 13198a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Window asks to hide input going forward"); 13204df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project hideCurrentInputLocked(0, null); 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN: 13248a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Window asks to hide input"); 13254df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project hideCurrentInputLocked(0, null); 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE: 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((softInputMode & 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) { 13308a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Window asks to show input going forward"); 13314df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null); 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE: 13358a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Window asks to always show input"); 13364df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null); 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Binder.restoreCallingIdentity(ident); 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1344ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void showInputMethodPickerFromClient(IInputMethodClient client) { 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCurClient == null || client == null 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || mCurClient.client.asBinder() != client.asBinder()) { 134947a44916e2fb33cf4751906386d5f5c903b28d8bsatok Slog.w(TAG, "Ignoring showInputMethodPickerFromClient of uid " 1350cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn + Binder.getCallingUid() + ": " + client); 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1353440aab54cab106030f1edafea4dec1f9d8624f9bsatok // Always call subtype picker, because subtype picker is a superset of input method 1354440aab54cab106030f1edafea4dec1f9d8624f9bsatok // picker. 1355ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mHandler.sendEmptyMessage(MSG_SHOW_IM_SUBTYPE_PICKER); 1356ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 1357ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 1358ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setInputMethod(IBinder token, String id) { 13602820351489537698ad153c6397edf3270455edc5satok setInputMethodWithSubtypeId(token, id, NOT_A_SUBTYPE_ID); 13612820351489537698ad153c6397edf3270455edc5satok } 13622820351489537698ad153c6397edf3270455edc5satok 13632820351489537698ad153c6397edf3270455edc5satok public void setInputMethodAndSubtype(IBinder token, String id, InputMethodSubtype subtype) { 13642820351489537698ad153c6397edf3270455edc5satok synchronized (mMethodMap) { 13652820351489537698ad153c6397edf3270455edc5satok if (subtype != null) { 13662820351489537698ad153c6397edf3270455edc5satok setInputMethodWithSubtypeId(token, id, getSubtypeIdFromHashCode( 13672820351489537698ad153c6397edf3270455edc5satok mMethodMap.get(id), subtype.hashCode())); 13682820351489537698ad153c6397edf3270455edc5satok } else { 13692820351489537698ad153c6397edf3270455edc5satok setInputMethod(token, id); 13702820351489537698ad153c6397edf3270455edc5satok } 13712820351489537698ad153c6397edf3270455edc5satok } 1372ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 1373ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 1374b416a71e56cdd50742eb897366a140775aa4cd61satok public void showInputMethodAndSubtypeEnablerFromClient( 1375217f548e79ab1ac3dd9e5be8fb6feaa6dcbe4000satok IInputMethodClient client, String inputMethodId) { 1376b416a71e56cdd50742eb897366a140775aa4cd61satok synchronized (mMethodMap) { 1377b416a71e56cdd50742eb897366a140775aa4cd61satok if (mCurClient == null || client == null 1378b416a71e56cdd50742eb897366a140775aa4cd61satok || mCurClient.client.asBinder() != client.asBinder()) { 1379b416a71e56cdd50742eb897366a140775aa4cd61satok Slog.w(TAG, "Ignoring showInputMethodAndSubtypeEnablerFromClient of: " + client); 1380b416a71e56cdd50742eb897366a140775aa4cd61satok } 13817fee71f66afef6421b92fa48e63d4bc73f5d0c27satok executeOrSendMessage(mCurMethod, mCaller.obtainMessageO( 13827fee71f66afef6421b92fa48e63d4bc73f5d0c27satok MSG_SHOW_IM_SUBTYPE_ENABLER, inputMethodId)); 1383b416a71e56cdd50742eb897366a140775aa4cd61satok } 1384b416a71e56cdd50742eb897366a140775aa4cd61satok } 1385b416a71e56cdd50742eb897366a140775aa4cd61satok 1386735cf38b8c7f8f91ad087511e44fe79018fa61d6satok public boolean switchToLastInputMethod(IBinder token) { 1387735cf38b8c7f8f91ad087511e44fe79018fa61d6satok synchronized (mMethodMap) { 1388c445bcd0bce630948ee029d7c70b28226f0b6c9csatok final Pair<String, String> lastIme = mSettings.getLastInputMethodAndSubtypeLocked(); 1389c445bcd0bce630948ee029d7c70b28226f0b6c9csatok if (lastIme == null) return false; 1390c445bcd0bce630948ee029d7c70b28226f0b6c9csatok final InputMethodInfo lastImi = mMethodMap.get(lastIme.first); 1391c445bcd0bce630948ee029d7c70b28226f0b6c9csatok if (lastImi == null) return false; 1392c445bcd0bce630948ee029d7c70b28226f0b6c9csatok 1393c445bcd0bce630948ee029d7c70b28226f0b6c9csatok final boolean imiIdIsSame = lastImi.getId().equals(mCurMethodId); 1394c445bcd0bce630948ee029d7c70b28226f0b6c9csatok final int lastSubtypeHash = Integer.valueOf(lastIme.second); 1395c445bcd0bce630948ee029d7c70b28226f0b6c9csatok // If the last IME is the same as the current IME and the last subtype is not defined, 1396c445bcd0bce630948ee029d7c70b28226f0b6c9csatok // there is no need to switch to the last IME. 1397c445bcd0bce630948ee029d7c70b28226f0b6c9csatok if (imiIdIsSame && lastSubtypeHash == NOT_A_SUBTYPE_ID) return false; 1398c445bcd0bce630948ee029d7c70b28226f0b6c9csatok 1399c445bcd0bce630948ee029d7c70b28226f0b6c9csatok int currentSubtypeHash = mCurrentSubtype == null ? NOT_A_SUBTYPE_ID 1400c445bcd0bce630948ee029d7c70b28226f0b6c9csatok : mCurrentSubtype.hashCode(); 1401c445bcd0bce630948ee029d7c70b28226f0b6c9csatok if (!imiIdIsSame || lastSubtypeHash != currentSubtypeHash) { 1402c445bcd0bce630948ee029d7c70b28226f0b6c9csatok if (DEBUG) { 1403c445bcd0bce630948ee029d7c70b28226f0b6c9csatok Slog.d(TAG, "Switch to: " + lastImi.getId() + ", " + lastIme.second + ", from: " 1404c445bcd0bce630948ee029d7c70b28226f0b6c9csatok + mCurMethodId + ", " + currentSubtypeHash); 1405735cf38b8c7f8f91ad087511e44fe79018fa61d6satok } 1406c445bcd0bce630948ee029d7c70b28226f0b6c9csatok setInputMethodWithSubtypeId(token, lastIme.first, getSubtypeIdFromHashCode( 1407c445bcd0bce630948ee029d7c70b28226f0b6c9csatok lastImi, lastSubtypeHash)); 1408c445bcd0bce630948ee029d7c70b28226f0b6c9csatok return true; 1409735cf38b8c7f8f91ad087511e44fe79018fa61d6satok } 1410735cf38b8c7f8f91ad087511e44fe79018fa61d6satok return false; 1411735cf38b8c7f8f91ad087511e44fe79018fa61d6satok } 1412735cf38b8c7f8f91ad087511e44fe79018fa61d6satok } 1413735cf38b8c7f8f91ad087511e44fe79018fa61d6satok 14142820351489537698ad153c6397edf3270455edc5satok private void setInputMethodWithSubtypeId(IBinder token, String id, int subtypeId) { 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (token == null) { 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission( 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.WRITE_SECURE_SETTINGS) 14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException( 14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Using null token requires permission " 14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + android.Manifest.permission.WRITE_SECURE_SETTINGS); 14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (mCurToken != token) { 1425cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn Slog.w(TAG, "Ignoring setInputMethod of uid " + Binder.getCallingUid() 1426cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn + " token: " + token); 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long ident = Binder.clearCallingIdentity(); 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1432ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok setInputMethodLocked(id, subtypeId); 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Binder.restoreCallingIdentity(ident); 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void hideMySoftInput(IBinder token, int flags) { 14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (token == null || mCurToken != token) { 1442cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn if (DEBUG) Slog.w(TAG, "Ignoring hideInputMethod of uid " 1443cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn + Binder.getCallingUid() + " token: " + token); 14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long ident = Binder.clearCallingIdentity(); 14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 14484df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project hideCurrentInputLocked(flags, null); 14494df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } finally { 14504df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project Binder.restoreCallingIdentity(ident); 14514df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 14524df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 14534df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 1454ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 14554df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project public void showMySoftInput(IBinder token, int flags) { 14564df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project synchronized (mMethodMap) { 14574df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project if (token == null || mCurToken != token) { 1458cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn Slog.w(TAG, "Ignoring showMySoftInput of uid " 1459cef65eeb0315c3118bf8860d6f723cb49ff6bc52Dianne Hackborn + Binder.getCallingUid() + " token: " + token); 14604df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project return; 14614df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } 14624df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project long ident = Binder.clearCallingIdentity(); 14634df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project try { 14644df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project showCurrentInputLocked(flags, null); 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Binder.restoreCallingIdentity(ident); 14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void setEnabledSessionInMainThread(SessionState session) { 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabledSession != session) { 14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabledSession != null) { 14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 14758a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Disabling: " + mEnabledSession); 14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledSession.method.setSessionEnabled( 14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledSession.session, false); 14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledSession = session; 14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 14838a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Enabling: " + mEnabledSession); 14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project session.method.setSessionEnabled( 14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project session.session, true); 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1490ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean handleMessage(Message msg) { 14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HandlerCaller.SomeArgs args; 14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (msg.what) { 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MSG_SHOW_IM_PICKER: 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project showInputMethodMenu(); 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1497ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1498ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok case MSG_SHOW_IM_SUBTYPE_PICKER: 1499ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok showInputMethodSubtypeMenu(); 1500ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return true; 1501ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 150247a44916e2fb33cf4751906386d5f5c903b28d8bsatok case MSG_SHOW_IM_SUBTYPE_ENABLER: 1503217f548e79ab1ac3dd9e5be8fb6feaa6dcbe4000satok args = (HandlerCaller.SomeArgs)msg.obj; 15047fee71f66afef6421b92fa48e63d4bc73f5d0c27satok showInputMethodAndSubtypeEnabler((String)args.arg1); 1505217f548e79ab1ac3dd9e5be8fb6feaa6dcbe4000satok return true; 1506217f548e79ab1ac3dd9e5be8fb6feaa6dcbe4000satok 1507217f548e79ab1ac3dd9e5be8fb6feaa6dcbe4000satok case MSG_SHOW_IM_CONFIG: 1508217f548e79ab1ac3dd9e5be8fb6feaa6dcbe4000satok showConfigureInputMethods(); 150947a44916e2fb33cf4751906386d5f5c903b28d8bsatok return true; 151047a44916e2fb33cf4751906386d5f5c903b28d8bsatok 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // --------------------------------------------------------- 1512ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MSG_UNBIND_INPUT: 15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((IInputMethod)msg.obj).unbindInput(); 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // There is nothing interesting about the method dying. 15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MSG_BIND_INPUT: 15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project args = (HandlerCaller.SomeArgs)msg.obj; 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((IInputMethod)args.arg1).bindInput((InputBinding)args.arg2); 15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MSG_SHOW_SOFT_INPUT: 15284df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project args = (HandlerCaller.SomeArgs)msg.obj; 15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15304df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project ((IInputMethod)args.arg1).showSoftInput(msg.arg1, 15314df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project (ResultReceiver)args.arg2); 15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MSG_HIDE_SOFT_INPUT: 15364df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project args = (HandlerCaller.SomeArgs)msg.obj; 15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15384df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project ((IInputMethod)args.arg1).hideSoftInput(0, 15394df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project (ResultReceiver)args.arg2); 15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MSG_ATTACH_TOKEN: 15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project args = (HandlerCaller.SomeArgs)msg.obj; 15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15468a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Sending attach of token: " + args.arg2); 15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((IInputMethod)args.arg1).attachToken((IBinder)args.arg2); 15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MSG_CREATE_SESSION: 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project args = (HandlerCaller.SomeArgs)msg.obj; 15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((IInputMethod)args.arg1).createSession( 15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (IInputMethodCallback)args.arg2); 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // --------------------------------------------------------- 1560ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MSG_START_INPUT: 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project args = (HandlerCaller.SomeArgs)msg.obj; 15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SessionState session = (SessionState)args.arg1; 15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setEnabledSessionInMainThread(session); 15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project session.method.startInput((IInputContext)args.arg2, 15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (EditorInfo)args.arg3); 15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MSG_RESTART_INPUT: 15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project args = (HandlerCaller.SomeArgs)msg.obj; 15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SessionState session = (SessionState)args.arg1; 15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setEnabledSessionInMainThread(session); 15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project session.method.restartInput((IInputContext)args.arg2, 15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (EditorInfo)args.arg3); 15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 1581ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // --------------------------------------------------------- 1583ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MSG_UNBIND_METHOD: 15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((IInputMethodClient)msg.obj).onUnbindMethod(msg.arg1); 15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // There is nothing interesting about the last client dying. 15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case MSG_BIND_METHOD: 15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project args = (HandlerCaller.SomeArgs)msg.obj; 15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((IInputMethodClient)args.arg1).onBindMethod( 15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (InputBindResult)args.arg2); 15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 15978a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Client died receiving input method " + args.arg2); 15989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16046da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger private boolean isSystemIme(InputMethodInfo inputMethod) { 16056da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger return (inputMethod.getServiceInfo().applicationInfo.flags 16066da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger & ApplicationInfo.FLAG_SYSTEM) != 0; 16076da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger } 16086da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger 1609586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa private static ArrayList<InputMethodSubtype> getSubtypes(InputMethodInfo imi) { 1610586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); 1611586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa final int subtypeCount = imi.getSubtypeCount(); 1612586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa for (int i = 0; i < subtypeCount; ++i) { 1613586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa subtypes.add(imi.getSubtypeAt(i)); 1614586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa } 1615586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa return subtypes; 1616586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa } 1617586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa 161821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn private boolean chooseNewDefaultIMELocked() { 1619d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok List<InputMethodInfo> enabled = mSettings.getEnabledInputMethodListLocked(); 16206da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger if (enabled != null && enabled.size() > 0) { 162183e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn // We'd prefer to fall back on a system IME, since that is safer. 162283e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn int i=enabled.size(); 162383e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn while (i > 0) { 162483e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn i--; 162583e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn if ((enabled.get(i).getServiceInfo().applicationInfo.flags 162683e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn & ApplicationInfo.FLAG_SYSTEM) != 0) { 162783e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn break; 162883e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn } 162983e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn } 1630ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok InputMethodInfo imi = enabled.get(i); 163103eb319a3a7fe6fe9ab9eba6fc1f727285850906satok if (DEBUG) { 163203eb319a3a7fe6fe9ab9eba6fc1f727285850906satok Slog.d(TAG, "New default IME was selected: " + imi.getId()); 163303eb319a3a7fe6fe9ab9eba6fc1f727285850906satok } 1634723a27ef3d7c94fc666abc52e0abd5e8526acb69satok resetSelectedInputMethodAndSubtypeLocked(imi.getId()); 16356da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger return true; 16366da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger } 16376da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger 16386da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger return false; 16396da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger } 16406da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger 16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void buildInputMethodListLocked(ArrayList<InputMethodInfo> list, 16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HashMap<String, InputMethodInfo> map) { 16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list.clear(); 16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project map.clear(); 1645ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageManager pm = mContext.getPackageManager(); 16477d3a5bcf300aea7bffb1d46f28e244ca807f5e82Dianne Hackborn final Configuration config = mRes.getConfiguration(); 1648e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani final boolean haveHardKeyboard = config.keyboard == Configuration.KEYBOARD_QWERTY; 1649e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani String disabledSysImes = Settings.Secure.getString(mContext.getContentResolver(), 1650e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani Secure.DISABLED_SYSTEM_INPUT_METHODS); 1651e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani if (disabledSysImes == null) disabledSysImes = ""; 16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project List<ResolveInfo> services = pm.queryIntentServices( 16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new Intent(InputMethod.SERVICE_INTERFACE), 16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageManager.GET_META_DATA); 1656ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < services.size(); ++i) { 16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ResolveInfo ri = services.get(i); 16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ServiceInfo si = ri.serviceInfo; 16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ComponentName compName = new ComponentName(si.packageName, si.name); 16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!android.Manifest.permission.BIND_INPUT_METHOD.equals( 16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project si.permission)) { 16638a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Skipping input method " + compName 16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ": it does not require the permission " 16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + android.Manifest.permission.BIND_INPUT_METHOD); 16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16698a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.d(TAG, "Checking " + compName); 16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputMethodInfo p = new InputMethodInfo(mContext, ri); 16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project list.add(p); 1674e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani final String id = p.getId(); 1675e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani map.put(id, p); 16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1677e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani // System IMEs are enabled by default, unless there's a hard keyboard 1678e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani // and the system IME was explicitly disabled 1679e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani if (isSystemIme(p) && (!haveHardKeyboard || disabledSysImes.indexOf(id) < 0)) { 1680e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani setInputMethodEnabledLocked(id, true); 16816da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger } 16826da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger 16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) { 16848a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.d(TAG, "Found a third-party input method " + p); 16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1686ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (XmlPullParserException e) { 16888a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Unable to load input method " + compName, e); 16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 16908a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "Unable to load input method " + compName, e); 16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16936da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger 16946da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger String defaultIme = Settings.Secure.getString(mContext 16956da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); 1696913a8925c07e854a80bf5df87561f290d3a56d61satok if (!TextUtils.isEmpty(defaultIme) && !map.containsKey(defaultIme)) { 169721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (chooseNewDefaultIMELocked()) { 16986da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger updateFromSettingsLocked(); 16996da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger } 17006da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger } 17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1702ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ---------------------------------------------------------------------- 1704ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1705ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private void showInputMethodMenu() { 1706ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok showInputMethodMenuInternal(false); 1707ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 1708ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 1709ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private void showInputMethodSubtypeMenu() { 1710ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok showInputMethodMenuInternal(true); 1711ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 1712ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 1713217f548e79ab1ac3dd9e5be8fb6feaa6dcbe4000satok private void showInputMethodAndSubtypeEnabler(String inputMethodId) { 1714f49688fa17b70313c0734f00df73bc3308a749e9Tadashi G. Takaoka Intent intent = new Intent(Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS); 171547a44916e2fb33cf4751906386d5f5c903b28d8bsatok intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 171686417ea3f8041481a085823a1aa9f66d747231e8satok | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 171786417ea3f8041481a085823a1aa9f66d747231e8satok | Intent.FLAG_ACTIVITY_CLEAR_TOP); 17187fee71f66afef6421b92fa48e63d4bc73f5d0c27satok if (!TextUtils.isEmpty(inputMethodId)) { 17192548020c364c4119d134c84cc7a00ffca2dcbe7bTadashi G. Takaoka intent.putExtra(Settings.EXTRA_INPUT_METHOD_ID, inputMethodId); 17207fee71f66afef6421b92fa48e63d4bc73f5d0c27satok } 1721217f548e79ab1ac3dd9e5be8fb6feaa6dcbe4000satok mContext.startActivity(intent); 1722217f548e79ab1ac3dd9e5be8fb6feaa6dcbe4000satok } 1723217f548e79ab1ac3dd9e5be8fb6feaa6dcbe4000satok 1724217f548e79ab1ac3dd9e5be8fb6feaa6dcbe4000satok private void showConfigureInputMethods() { 1725217f548e79ab1ac3dd9e5be8fb6feaa6dcbe4000satok Intent intent = new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS); 1726217f548e79ab1ac3dd9e5be8fb6feaa6dcbe4000satok intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 1727217f548e79ab1ac3dd9e5be8fb6feaa6dcbe4000satok | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 1728217f548e79ab1ac3dd9e5be8fb6feaa6dcbe4000satok | Intent.FLAG_ACTIVITY_CLEAR_TOP); 172947a44916e2fb33cf4751906386d5f5c903b28d8bsatok mContext.startActivity(intent); 173047a44916e2fb33cf4751906386d5f5c903b28d8bsatok } 173147a44916e2fb33cf4751906386d5f5c903b28d8bsatok 1732ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private void showInputMethodMenuInternal(boolean showSubtypes) { 17338a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Show switching menu"); 17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Context context = mContext; 1736ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final PackageManager pm = context.getPackageManager(); 1738ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String lastInputMethodId = Settings.Secure.getString(context 17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); 1741ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok int lastInputMethodSubtypeId = getSelectedInputMethodSubtypeId(lastInputMethodId); 17428a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Current IME: " + lastInputMethodId); 1743ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 17447f35c8cc88bea5230f001dd4356f864845d202e5satok synchronized (mMethodMap) { 1745bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok final HashMap<InputMethodInfo, List<InputMethodSubtype>> immis = 1746bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked(); 17477f35c8cc88bea5230f001dd4356f864845d202e5satok if (immis == null || immis.size() == 0) { 17487f35c8cc88bea5230f001dd4356f864845d202e5satok return; 17497f35c8cc88bea5230f001dd4356f864845d202e5satok } 1750ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 17518cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn hideInputMethodMenuLocked(); 17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1753ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok final Map<CharSequence, Pair<InputMethodInfo, Integer>> imMap = 1754ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok new TreeMap<CharSequence, Pair<InputMethodInfo, Integer>>(Collator.getInstance()); 1755913a8925c07e854a80bf5df87561f290d3a56d61satok 1756bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok for (InputMethodInfo imi: immis.keySet()) { 1757bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok if (imi == null) continue; 1758bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypeList = immis.get(imi); 17597f35c8cc88bea5230f001dd4356f864845d202e5satok HashSet<String> enabledSubtypeSet = new HashSet<String>(); 1760bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok for (InputMethodSubtype subtype: explicitlyOrImplicitlyEnabledSubtypeList) { 1761bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok enabledSubtypeSet.add(String.valueOf(subtype.hashCode())); 17627f35c8cc88bea5230f001dd4356f864845d202e5satok } 1763bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok ArrayList<InputMethodSubtype> subtypes = getSubtypes(imi); 1764bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok CharSequence label = imi.loadLabel(pm); 17657f35c8cc88bea5230f001dd4356f864845d202e5satok if (showSubtypes && enabledSubtypeSet.size() > 0) { 1766bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok final int subtypeCount = imi.getSubtypeCount(); 1767586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa for (int j = 0; j < subtypeCount; ++j) { 1768bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok InputMethodSubtype subtype = imi.getSubtypeAt(j); 17697f35c8cc88bea5230f001dd4356f864845d202e5satok if (enabledSubtypeSet.contains(String.valueOf(subtype.hashCode()))) { 17707f35c8cc88bea5230f001dd4356f864845d202e5satok CharSequence title; 17717f35c8cc88bea5230f001dd4356f864845d202e5satok int nameResId = subtype.getNameResId(); 17729ef0283bdcd9534cc09ae37eb2b78771b95247b5satok String mode = subtype.getMode(); 17737f35c8cc88bea5230f001dd4356f864845d202e5satok if (nameResId != 0) { 1774bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok title = pm.getText(imi.getPackageName(), nameResId, 1775bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok imi.getServiceInfo().applicationInfo); 17767f35c8cc88bea5230f001dd4356f864845d202e5satok } else { 17777f35c8cc88bea5230f001dd4356f864845d202e5satok CharSequence language = subtype.getLocale(); 17787f35c8cc88bea5230f001dd4356f864845d202e5satok // TODO: Use more friendly Title and UI 17797f35c8cc88bea5230f001dd4356f864845d202e5satok title = label + "," + (mode == null ? "" : mode) + "," 17807f35c8cc88bea5230f001dd4356f864845d202e5satok + (language == null ? "" : language); 17817f35c8cc88bea5230f001dd4356f864845d202e5satok } 1782bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok imMap.put(title, new Pair<InputMethodInfo, Integer>(imi, j)); 1783ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 1784ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 1785ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } else { 1786ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok imMap.put(label, 1787bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok new Pair<InputMethodInfo, Integer>(imi, NOT_A_SUBTYPE_ID)); 1788ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1790913a8925c07e854a80bf5df87561f290d3a56d61satok 1791bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok final int N = imMap.size(); 1792913a8925c07e854a80bf5df87561f290d3a56d61satok mItems = imMap.keySet().toArray(new CharSequence[N]); 1793ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mIms = new InputMethodInfo[N]; 1794ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeIds = new int[N]; 17958cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn int checkedItem = 0; 17968cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn for (int i = 0; i < N; ++i) { 1797ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok Pair<InputMethodInfo, Integer> value = imMap.get(mItems[i]); 1798ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mIms[i] = value.first; 1799ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok mSubtypeIds[i] = value.second; 18008cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn if (mIms[i].getId().equals(lastInputMethodId)) { 1801ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok int subtypeId = mSubtypeIds[i]; 1802ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok if ((subtypeId == NOT_A_SUBTYPE_ID) 1803ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok || (lastInputMethodSubtypeId == NOT_A_SUBTYPE_ID && subtypeId == 0) 1804ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok || (subtypeId == lastInputMethodSubtypeId)) { 1805ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok checkedItem = i; 1806ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 18078cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn } 18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1809ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 18108cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn AlertDialog.OnClickListener adocl = new AlertDialog.OnClickListener() { 18118cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn public void onClick(DialogInterface dialog, int which) { 18128cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn hideInputMethodMenu(); 18138cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn } 18148cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn }; 1815d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok 18168cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn TypedArray a = context.obtainStyledAttributes(null, 18178cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn com.android.internal.R.styleable.DialogPreference, 18188cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn com.android.internal.R.attr.alertDialogStyle, 0); 18198cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn mDialogBuilder = new AlertDialog.Builder(context) 18208cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn .setTitle(com.android.internal.R.string.select_input_method) 18218cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn .setOnCancelListener(new OnCancelListener() { 18228cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn public void onCancel(DialogInterface dialog) { 18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hideInputMethodMenu(); 18248cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn } 18258cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn }) 18268cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn .setIcon(a.getDrawable( 18278cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn com.android.internal.R.styleable.DialogPreference_dialogTitle)); 18288cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn a.recycle(); 1829d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok 18308cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn mDialogBuilder.setSingleChoiceItems(mItems, checkedItem, 18318cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn new AlertDialog.OnClickListener() { 18328cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn public void onClick(DialogInterface dialog, int which) { 18338cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn synchronized (mMethodMap) { 1834ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok if (mIms == null || mIms.length <= which 1835ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok || mSubtypeIds == null || mSubtypeIds.length <= which) { 18368cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn return; 18378cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn } 18388cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn InputMethodInfo im = mIms[which]; 1839ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok int subtypeId = mSubtypeIds[which]; 18408cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn hideInputMethodMenu(); 18418cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn if (im != null) { 1842ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok if ((subtypeId < 0) 1843586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa || (subtypeId >= im.getSubtypeCount())) { 1844ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok subtypeId = NOT_A_SUBTYPE_ID; 1845ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 1846ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok setInputMethodLocked(im.getId(), subtypeId); 18478cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn } 184820cb56e26e91df91bd64d4251222e0d421cdbe47Dianne Hackborn } 18499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18508cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn }); 18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18527f35c8cc88bea5230f001dd4356f864845d202e5satok if (showSubtypes) { 185382beadfa067b1e286fa604f8d7960d769411c954satok mDialogBuilder.setPositiveButton( 185482beadfa067b1e286fa604f8d7960d769411c954satok com.android.internal.R.string.configure_input_methods, 18557f35c8cc88bea5230f001dd4356f864845d202e5satok new DialogInterface.OnClickListener() { 18567f35c8cc88bea5230f001dd4356f864845d202e5satok public void onClick(DialogInterface dialog, int whichButton) { 1857217f548e79ab1ac3dd9e5be8fb6feaa6dcbe4000satok showConfigureInputMethods(); 18587f35c8cc88bea5230f001dd4356f864845d202e5satok } 18597f35c8cc88bea5230f001dd4356f864845d202e5satok }); 18607f35c8cc88bea5230f001dd4356f864845d202e5satok } 18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSwitchingDialog = mDialogBuilder.create(); 18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSwitchingDialog.getWindow().setType( 18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG); 18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSwitchingDialog.show(); 18659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1867ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void hideInputMethodMenu() { 1869105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project synchronized (mMethodMap) { 1870105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project hideInputMethodMenuLocked(); 1871105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 1872105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 1873ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1874105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project void hideInputMethodMenuLocked() { 18758a9b22056b13477f59df934928c00c58b5871c95Joe Onorato if (DEBUG) Slog.v(TAG, "Hide switching menu"); 18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1877105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (mSwitchingDialog != null) { 1878105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mSwitchingDialog.dismiss(); 1879105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mSwitchingDialog = null; 18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1881ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1882105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mDialogBuilder = null; 1883105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mItems = null; 1884105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mIms = null; 18859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1886ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ---------------------------------------------------------------------- 1888ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean setInputMethodEnabled(String id, boolean enabled) { 18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission( 18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.WRITE_SECURE_SETTINGS) 18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException( 18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Requires permission " 18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + android.Manifest.permission.WRITE_SECURE_SETTINGS); 18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 189821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long ident = Binder.clearCallingIdentity(); 19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 190121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return setInputMethodEnabledLocked(id, enabled); 190221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } finally { 190321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn Binder.restoreCallingIdentity(ident); 190421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 190521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 190621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 190721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn 190821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn boolean setInputMethodEnabledLocked(String id, boolean enabled) { 190921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn // Make sure this is a valid input method. 191021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn InputMethodInfo imm = mMethodMap.get(id); 191121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (imm == null) { 1912d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok throw new IllegalArgumentException("Unknown id: " + mCurMethodId); 191321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 1914ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1915d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok List<Pair<String, ArrayList<String>>> enabledInputMethodsList = mSettings 1916d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok .getEnabledInputMethodsAndSubtypeListLocked(); 1917ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 1918d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok if (enabled) { 1919d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok for (Pair<String, ArrayList<String>> pair: enabledInputMethodsList) { 1920d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok if (pair.first.equals(id)) { 1921d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // We are enabling this input method, but it is already enabled. 1922d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // Nothing to do. The previous state was enabled. 1923d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok return true; 19249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 192521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 1926d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok mSettings.appendAndPutEnabledInputMethodLocked(id, false); 1927d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // Previous state was disabled. 1928d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok return false; 1929d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } else { 1930d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok StringBuilder builder = new StringBuilder(); 1931d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok if (mSettings.buildAndPutEnabledInputMethodsStrRemovingIdLocked( 1932d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok builder, enabledInputMethodsList, id)) { 1933d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // Disabled input method is currently selected, switch to another one. 1934d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok String selId = Settings.Secure.getString(mContext.getContentResolver(), 1935d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok Settings.Secure.DEFAULT_INPUT_METHOD); 193603eb319a3a7fe6fe9ab9eba6fc1f727285850906satok if (id.equals(selId) && !chooseNewDefaultIMELocked()) { 193703eb319a3a7fe6fe9ab9eba6fc1f727285850906satok Slog.i(TAG, "Can't find new IME, unsetting the current input method."); 193803eb319a3a7fe6fe9ab9eba6fc1f727285850906satok resetSelectedInputMethodAndSubtypeLocked(""); 1939d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 1940d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // Previous state was enabled. 1941d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok return true; 1942d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } else { 1943d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // We are disabling the input method but it is already disabled. 1944d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // Nothing to do. The previous state was disabled. 19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19494df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 195057ffc00239edcfe733832771e1429fca20182207satok private boolean canAddToLastInputMethod(InputMethodSubtype subtype) { 195157ffc00239edcfe733832771e1429fca20182207satok if (subtype == null) return true; 195257ffc00239edcfe733832771e1429fca20182207satok String[] extraValues = subtype.getExtraValue().split(","); 195357ffc00239edcfe733832771e1429fca20182207satok final int N = extraValues.length; 195457ffc00239edcfe733832771e1429fca20182207satok for (int i = 0; i < N; ++i) { 195557ffc00239edcfe733832771e1429fca20182207satok if (SUBTYPE_EXTRAVALUE_EXCLUDE_FROM_LAST_IME.equals(extraValues[i])) { 195657ffc00239edcfe733832771e1429fca20182207satok return false; 195757ffc00239edcfe733832771e1429fca20182207satok } 195857ffc00239edcfe733832771e1429fca20182207satok } 195957ffc00239edcfe733832771e1429fca20182207satok return true; 196057ffc00239edcfe733832771e1429fca20182207satok } 196157ffc00239edcfe733832771e1429fca20182207satok 1962723a27ef3d7c94fc666abc52e0abd5e8526acb69satok private void saveCurrentInputMethodAndSubtypeToHistory() { 1963723a27ef3d7c94fc666abc52e0abd5e8526acb69satok String subtypeId = NOT_A_SUBTYPE_ID_STR; 1964723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (mCurrentSubtype != null) { 1965723a27ef3d7c94fc666abc52e0abd5e8526acb69satok subtypeId = String.valueOf(mCurrentSubtype.hashCode()); 1966723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 196757ffc00239edcfe733832771e1429fca20182207satok if (canAddToLastInputMethod(mCurrentSubtype)) { 196857ffc00239edcfe733832771e1429fca20182207satok mSettings.addSubtypeToHistory(mCurMethodId, subtypeId); 196957ffc00239edcfe733832771e1429fca20182207satok } 1970ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 1971ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 1972723a27ef3d7c94fc666abc52e0abd5e8526acb69satok private void setSelectedInputMethodAndSubtypeLocked(InputMethodInfo imi, int subtypeId, 1973723a27ef3d7c94fc666abc52e0abd5e8526acb69satok boolean setSubtypeOnly) { 19744d733290a112fbe7ca5631ee870094b538f39d80satok mOldSystemSettingsVersion = getSystemSettingsVersion(); 1975723a27ef3d7c94fc666abc52e0abd5e8526acb69satok // Update the history of InputMethod and Subtype 1976723a27ef3d7c94fc666abc52e0abd5e8526acb69satok saveCurrentInputMethodAndSubtypeToHistory(); 1977723a27ef3d7c94fc666abc52e0abd5e8526acb69satok 1978723a27ef3d7c94fc666abc52e0abd5e8526acb69satok // Set Subtype here 1979723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (imi == null || subtypeId < 0) { 1980723a27ef3d7c94fc666abc52e0abd5e8526acb69satok mSettings.putSelectedSubtype(NOT_A_SUBTYPE_ID); 19810ba75bb22c2992f649ee5f7605a2b45442ad4862Tadashi G. Takaoka mCurrentSubtype = null; 1982723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } else { 1983586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa if (subtypeId < imi.getSubtypeCount()) { 1984586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa InputMethodSubtype subtype = imi.getSubtypeAt(subtypeId); 1985586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa mSettings.putSelectedSubtype(subtype.hashCode()); 1986586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa mCurrentSubtype = subtype; 1987723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } else { 1988723a27ef3d7c94fc666abc52e0abd5e8526acb69satok mSettings.putSelectedSubtype(NOT_A_SUBTYPE_ID); 1989723a27ef3d7c94fc666abc52e0abd5e8526acb69satok mCurrentSubtype = null; 1990723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 1991723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 1992723a27ef3d7c94fc666abc52e0abd5e8526acb69satok 1993723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (!setSubtypeOnly) { 1994723a27ef3d7c94fc666abc52e0abd5e8526acb69satok // Set InputMethod here 1995723a27ef3d7c94fc666abc52e0abd5e8526acb69satok mSettings.putSelectedInputMethod(imi != null ? imi.getId() : ""); 19961ab852fbcfe155c9d4373b7130f8515591669634satok } 1997ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 1998ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 1999723a27ef3d7c94fc666abc52e0abd5e8526acb69satok private void resetSelectedInputMethodAndSubtypeLocked(String newDefaultIme) { 2000723a27ef3d7c94fc666abc52e0abd5e8526acb69satok InputMethodInfo imi = mMethodMap.get(newDefaultIme); 2001723a27ef3d7c94fc666abc52e0abd5e8526acb69satok int lastSubtypeId = NOT_A_SUBTYPE_ID; 2002723a27ef3d7c94fc666abc52e0abd5e8526acb69satok // newDefaultIme is empty when there is no candidate for the selected IME. 2003723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (imi != null && !TextUtils.isEmpty(newDefaultIme)) { 2004723a27ef3d7c94fc666abc52e0abd5e8526acb69satok String subtypeHashCode = mSettings.getLastSubtypeForInputMethodLocked(newDefaultIme); 2005723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (subtypeHashCode != null) { 2006723a27ef3d7c94fc666abc52e0abd5e8526acb69satok try { 2007723a27ef3d7c94fc666abc52e0abd5e8526acb69satok lastSubtypeId = getSubtypeIdFromHashCode( 2008723a27ef3d7c94fc666abc52e0abd5e8526acb69satok imi, Integer.valueOf(subtypeHashCode)); 2009723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } catch (NumberFormatException e) { 2010723a27ef3d7c94fc666abc52e0abd5e8526acb69satok Slog.w(TAG, "HashCode for subtype looks broken: " + subtypeHashCode, e); 2011723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2012723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2013723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2014723a27ef3d7c94fc666abc52e0abd5e8526acb69satok setSelectedInputMethodAndSubtypeLocked(imi, lastSubtypeId, false); 2015723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2016723a27ef3d7c94fc666abc52e0abd5e8526acb69satok 2017ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok private int getSelectedInputMethodSubtypeId(String id) { 2018ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok InputMethodInfo imi = mMethodMap.get(id); 2019ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok if (imi == null) { 2020ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return NOT_A_SUBTYPE_ID; 2021ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 2022ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok int subtypeId; 2023ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok try { 2024ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok subtypeId = Settings.Secure.getInt(mContext.getContentResolver(), 2025ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE); 2026ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } catch (SettingNotFoundException e) { 2027ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return NOT_A_SUBTYPE_ID; 2028ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 2029723a27ef3d7c94fc666abc52e0abd5e8526acb69satok return getSubtypeIdFromHashCode(imi, subtypeId); 2030723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2031723a27ef3d7c94fc666abc52e0abd5e8526acb69satok 2032723a27ef3d7c94fc666abc52e0abd5e8526acb69satok private int getSubtypeIdFromHashCode(InputMethodInfo imi, int subtypeHashCode) { 20332820351489537698ad153c6397edf3270455edc5satok if (imi != null) { 2034586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa final int subtypeCount = imi.getSubtypeCount(); 2035586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa for (int i = 0; i < subtypeCount; ++i) { 2036586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa InputMethodSubtype ims = imi.getSubtypeAt(i); 20372820351489537698ad153c6397edf3270455edc5satok if (subtypeHashCode == ims.hashCode()) { 20382820351489537698ad153c6397edf3270455edc5satok return i; 20392820351489537698ad153c6397edf3270455edc5satok } 2040ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 2041ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 2042ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok return NOT_A_SUBTYPE_ID; 2043ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 2044ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 2045df31ae6a3011d47421a6ac10021f9649dc34a156satok private static ArrayList<InputMethodSubtype> getApplicableSubtypesLocked( 2046df31ae6a3011d47421a6ac10021f9649dc34a156satok Resources res, List<InputMethodSubtype> subtypes) { 2047df31ae6a3011d47421a6ac10021f9649dc34a156satok final String systemLocale = res.getConfiguration().locale.toString(); 20483da922367c0dbe67b97fe97fcfca13fd93602f7asatok if (TextUtils.isEmpty(systemLocale)) return new ArrayList<InputMethodSubtype>(); 20493da922367c0dbe67b97fe97fcfca13fd93602f7asatok HashMap<String, InputMethodSubtype> applicableModeAndSubtypesMap = 20503da922367c0dbe67b97fe97fcfca13fd93602f7asatok new HashMap<String, InputMethodSubtype>(); 205116331c8a1d33defccc5cbb18694def79196c921bsatok final int N = subtypes.size(); 205216331c8a1d33defccc5cbb18694def79196c921bsatok boolean containsKeyboardSubtype = false; 205316331c8a1d33defccc5cbb18694def79196c921bsatok for (int i = 0; i < N; ++i) { 205416331c8a1d33defccc5cbb18694def79196c921bsatok InputMethodSubtype subtype = subtypes.get(i); 20553da922367c0dbe67b97fe97fcfca13fd93602f7asatok final String locale = subtype.getLocale(); 20563da922367c0dbe67b97fe97fcfca13fd93602f7asatok final String mode = subtype.getMode(); 20573da922367c0dbe67b97fe97fcfca13fd93602f7asatok // When system locale starts with subtype's locale, that subtype will be applicable 20583da922367c0dbe67b97fe97fcfca13fd93602f7asatok // for system locale 20593da922367c0dbe67b97fe97fcfca13fd93602f7asatok // For instance, it's clearly applicable for cases like system locale = en_US and 20603da922367c0dbe67b97fe97fcfca13fd93602f7asatok // subtype = en, but it is not necessarily considered applicable for cases like system 20613da922367c0dbe67b97fe97fcfca13fd93602f7asatok // locale = en and subtype = en_US. 20623da922367c0dbe67b97fe97fcfca13fd93602f7asatok // We just call systemLocale.startsWith(locale) in this function because there is no 20633da922367c0dbe67b97fe97fcfca13fd93602f7asatok // need to find applicable subtypes aggressively unlike 20643da922367c0dbe67b97fe97fcfca13fd93602f7asatok // findLastResortApplicableSubtypeLocked. 20653da922367c0dbe67b97fe97fcfca13fd93602f7asatok if (systemLocale.startsWith(locale)) { 20663da922367c0dbe67b97fe97fcfca13fd93602f7asatok InputMethodSubtype applicableSubtype = applicableModeAndSubtypesMap.get(mode); 20673da922367c0dbe67b97fe97fcfca13fd93602f7asatok // If more applicable subtypes are contained, skip. 20683da922367c0dbe67b97fe97fcfca13fd93602f7asatok if (applicableSubtype != null 20693da922367c0dbe67b97fe97fcfca13fd93602f7asatok && systemLocale.equals(applicableSubtype.getLocale())) continue; 20703da922367c0dbe67b97fe97fcfca13fd93602f7asatok applicableModeAndSubtypesMap.put(mode, subtype); 207116331c8a1d33defccc5cbb18694def79196c921bsatok if (!containsKeyboardSubtype 207216331c8a1d33defccc5cbb18694def79196c921bsatok && SUBTYPE_MODE_KEYBOARD.equalsIgnoreCase(subtype.getMode())) { 207316331c8a1d33defccc5cbb18694def79196c921bsatok containsKeyboardSubtype = true; 207416331c8a1d33defccc5cbb18694def79196c921bsatok } 207516331c8a1d33defccc5cbb18694def79196c921bsatok } 207616331c8a1d33defccc5cbb18694def79196c921bsatok } 20773da922367c0dbe67b97fe97fcfca13fd93602f7asatok ArrayList<InputMethodSubtype> applicableSubtypes = new ArrayList<InputMethodSubtype>( 20783da922367c0dbe67b97fe97fcfca13fd93602f7asatok applicableModeAndSubtypesMap.values()); 207916331c8a1d33defccc5cbb18694def79196c921bsatok if (!containsKeyboardSubtype) { 208016331c8a1d33defccc5cbb18694def79196c921bsatok InputMethodSubtype lastResortKeyboardSubtype = findLastResortApplicableSubtypeLocked( 2081df31ae6a3011d47421a6ac10021f9649dc34a156satok res, subtypes, SUBTYPE_MODE_KEYBOARD, systemLocale, true); 208216331c8a1d33defccc5cbb18694def79196c921bsatok if (lastResortKeyboardSubtype != null) { 208316331c8a1d33defccc5cbb18694def79196c921bsatok applicableSubtypes.add(lastResortKeyboardSubtype); 208416331c8a1d33defccc5cbb18694def79196c921bsatok } 208516331c8a1d33defccc5cbb18694def79196c921bsatok } 208616331c8a1d33defccc5cbb18694def79196c921bsatok return applicableSubtypes; 208716331c8a1d33defccc5cbb18694def79196c921bsatok } 208816331c8a1d33defccc5cbb18694def79196c921bsatok 20894e4569dab5c75804b01a19b2d6e6101b445c1c68satok /** 20904e4569dab5c75804b01a19b2d6e6101b445c1c68satok * If there are no selected subtypes, tries finding the most applicable one according to the 20914e4569dab5c75804b01a19b2d6e6101b445c1c68satok * given locale. 20924e4569dab5c75804b01a19b2d6e6101b445c1c68satok * @param subtypes this function will search the most applicable subtype in subtypes 20934e4569dab5c75804b01a19b2d6e6101b445c1c68satok * @param mode subtypes will be filtered by mode 20944e4569dab5c75804b01a19b2d6e6101b445c1c68satok * @param locale subtypes will be filtered by locale 20957599a7fb1ab5b75ca801f7d7e448f4c097320e01satok * @param canIgnoreLocaleAsLastResort if this function can't find the most applicable subtype, 20967599a7fb1ab5b75ca801f7d7e448f4c097320e01satok * it will return the first subtype matched with mode 20974e4569dab5c75804b01a19b2d6e6101b445c1c68satok * @return the most applicable subtypeId 20984e4569dab5c75804b01a19b2d6e6101b445c1c68satok */ 2099df31ae6a3011d47421a6ac10021f9649dc34a156satok private static InputMethodSubtype findLastResortApplicableSubtypeLocked( 2100df31ae6a3011d47421a6ac10021f9649dc34a156satok Resources res, List<InputMethodSubtype> subtypes, String mode, String locale, 21017599a7fb1ab5b75ca801f7d7e448f4c097320e01satok boolean canIgnoreLocaleAsLastResort) { 21028fbb1e84ee6497f89322f2e40453c1cfa83fb4efsatok if (subtypes == null || subtypes.size() == 0) { 2103cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok return null; 21048fbb1e84ee6497f89322f2e40453c1cfa83fb4efsatok } 21054e4569dab5c75804b01a19b2d6e6101b445c1c68satok if (TextUtils.isEmpty(locale)) { 2106df31ae6a3011d47421a6ac10021f9649dc34a156satok locale = res.getConfiguration().locale.toString(); 21074e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 21088fbb1e84ee6497f89322f2e40453c1cfa83fb4efsatok final String language = locale.substring(0, 2); 21098fbb1e84ee6497f89322f2e40453c1cfa83fb4efsatok boolean partialMatchFound = false; 2110cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok InputMethodSubtype applicableSubtype = null; 21117599a7fb1ab5b75ca801f7d7e448f4c097320e01satok InputMethodSubtype firstMatchedModeSubtype = null; 211216331c8a1d33defccc5cbb18694def79196c921bsatok final int N = subtypes.size(); 211316331c8a1d33defccc5cbb18694def79196c921bsatok for (int i = 0; i < N; ++i) { 2114cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok InputMethodSubtype subtype = subtypes.get(i); 2115cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok final String subtypeLocale = subtype.getLocale(); 2116d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok // An applicable subtype should match "mode". If mode is null, mode will be ignored, 2117d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok // and all subtypes with all modes can be candidates. 2118d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok if (mode == null || subtypes.get(i).getMode().equalsIgnoreCase(mode)) { 21197599a7fb1ab5b75ca801f7d7e448f4c097320e01satok if (firstMatchedModeSubtype == null) { 21207599a7fb1ab5b75ca801f7d7e448f4c097320e01satok firstMatchedModeSubtype = subtype; 21217599a7fb1ab5b75ca801f7d7e448f4c097320e01satok } 21229ef0283bdcd9534cc09ae37eb2b78771b95247b5satok if (locale.equals(subtypeLocale)) { 21239ef0283bdcd9534cc09ae37eb2b78771b95247b5satok // Exact match (e.g. system locale is "en_US" and subtype locale is "en_US") 2124cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok applicableSubtype = subtype; 21259ef0283bdcd9534cc09ae37eb2b78771b95247b5satok break; 21269ef0283bdcd9534cc09ae37eb2b78771b95247b5satok } else if (!partialMatchFound && subtypeLocale.startsWith(language)) { 21279ef0283bdcd9534cc09ae37eb2b78771b95247b5satok // Partial match (e.g. system locale is "en_US" and subtype locale is "en") 2128cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok applicableSubtype = subtype; 21299ef0283bdcd9534cc09ae37eb2b78771b95247b5satok partialMatchFound = true; 21309ef0283bdcd9534cc09ae37eb2b78771b95247b5satok } 21318fbb1e84ee6497f89322f2e40453c1cfa83fb4efsatok } 21328fbb1e84ee6497f89322f2e40453c1cfa83fb4efsatok } 21338fbb1e84ee6497f89322f2e40453c1cfa83fb4efsatok 21347599a7fb1ab5b75ca801f7d7e448f4c097320e01satok if (applicableSubtype == null && canIgnoreLocaleAsLastResort) { 21357599a7fb1ab5b75ca801f7d7e448f4c097320e01satok return firstMatchedModeSubtype; 213616331c8a1d33defccc5cbb18694def79196c921bsatok } 213716331c8a1d33defccc5cbb18694def79196c921bsatok 21388fbb1e84ee6497f89322f2e40453c1cfa83fb4efsatok // The first subtype applicable to the system locale will be defined as the most applicable 21398fbb1e84ee6497f89322f2e40453c1cfa83fb4efsatok // subtype. 21408fbb1e84ee6497f89322f2e40453c1cfa83fb4efsatok if (DEBUG) { 214116331c8a1d33defccc5cbb18694def79196c921bsatok if (applicableSubtype != null) { 214216331c8a1d33defccc5cbb18694def79196c921bsatok Slog.d(TAG, "Applicable InputMethodSubtype was found: " 214316331c8a1d33defccc5cbb18694def79196c921bsatok + applicableSubtype.getMode() + "," + applicableSubtype.getLocale()); 214416331c8a1d33defccc5cbb18694def79196c921bsatok } 21458fbb1e84ee6497f89322f2e40453c1cfa83fb4efsatok } 2146cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok return applicableSubtype; 21478fbb1e84ee6497f89322f2e40453c1cfa83fb4efsatok } 21488fbb1e84ee6497f89322f2e40453c1cfa83fb4efsatok 21494e4569dab5c75804b01a19b2d6e6101b445c1c68satok // If there are no selected shortcuts, tries finding the most applicable ones. 21504e4569dab5c75804b01a19b2d6e6101b445c1c68satok private Pair<InputMethodInfo, InputMethodSubtype> 21514e4569dab5c75804b01a19b2d6e6101b445c1c68satok findLastResortApplicableShortcutInputMethodAndSubtypeLocked(String mode) { 21524e4569dab5c75804b01a19b2d6e6101b445c1c68satok List<InputMethodInfo> imis = mSettings.getEnabledInputMethodListLocked(); 21534e4569dab5c75804b01a19b2d6e6101b445c1c68satok InputMethodInfo mostApplicableIMI = null; 2154cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok InputMethodSubtype mostApplicableSubtype = null; 21554e4569dab5c75804b01a19b2d6e6101b445c1c68satok boolean foundInSystemIME = false; 21564e4569dab5c75804b01a19b2d6e6101b445c1c68satok 21574e4569dab5c75804b01a19b2d6e6101b445c1c68satok // Search applicable subtype for each InputMethodInfo 21584e4569dab5c75804b01a19b2d6e6101b445c1c68satok for (InputMethodInfo imi: imis) { 21597599a7fb1ab5b75ca801f7d7e448f4c097320e01satok final String imiId = imi.getId(); 21607599a7fb1ab5b75ca801f7d7e448f4c097320e01satok if (foundInSystemIME && !imiId.equals(mCurMethodId)) { 21617599a7fb1ab5b75ca801f7d7e448f4c097320e01satok continue; 21627599a7fb1ab5b75ca801f7d7e448f4c097320e01satok } 2163cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok InputMethodSubtype subtype = null; 2164df31ae6a3011d47421a6ac10021f9649dc34a156satok final List<InputMethodSubtype> enabledSubtypes = 2165df31ae6a3011d47421a6ac10021f9649dc34a156satok getEnabledInputMethodSubtypeList(imi, true); 2166df31ae6a3011d47421a6ac10021f9649dc34a156satok // 1. Search by the current subtype's locale from enabledSubtypes. 21674e4569dab5c75804b01a19b2d6e6101b445c1c68satok if (mCurrentSubtype != null) { 2168cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok subtype = findLastResortApplicableSubtypeLocked( 2169df31ae6a3011d47421a6ac10021f9649dc34a156satok mRes, enabledSubtypes, mode, mCurrentSubtype.getLocale(), false); 21704e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 2171df31ae6a3011d47421a6ac10021f9649dc34a156satok // 2. Search by the system locale from enabledSubtypes. 2172df31ae6a3011d47421a6ac10021f9649dc34a156satok // 3. Search the first enabled subtype matched with mode from enabledSubtypes. 2173cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok if (subtype == null) { 2174cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok subtype = findLastResortApplicableSubtypeLocked( 2175df31ae6a3011d47421a6ac10021f9649dc34a156satok mRes, enabledSubtypes, mode, null, true); 21767599a7fb1ab5b75ca801f7d7e448f4c097320e01satok } 21777599a7fb1ab5b75ca801f7d7e448f4c097320e01satok // 4. Search by the current subtype's locale from all subtypes. 21787599a7fb1ab5b75ca801f7d7e448f4c097320e01satok if (subtype == null && mCurrentSubtype != null) { 21797599a7fb1ab5b75ca801f7d7e448f4c097320e01satok subtype = findLastResortApplicableSubtypeLocked( 2180586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa mRes, getSubtypes(imi), mode, mCurrentSubtype.getLocale(), false); 21814e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 21827599a7fb1ab5b75ca801f7d7e448f4c097320e01satok // 5. Search by the system locale from all subtypes. 21837599a7fb1ab5b75ca801f7d7e448f4c097320e01satok // 6. Search the first enabled subtype matched with mode from all subtypes. 2184cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok if (subtype == null) { 21857599a7fb1ab5b75ca801f7d7e448f4c097320e01satok subtype = findLastResortApplicableSubtypeLocked( 2186586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa mRes, getSubtypes(imi), mode, null, true); 21874e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 2188cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok if (subtype != null) { 21897599a7fb1ab5b75ca801f7d7e448f4c097320e01satok if (imiId.equals(mCurMethodId)) { 21904e4569dab5c75804b01a19b2d6e6101b445c1c68satok // The current input method is the most applicable IME. 21914e4569dab5c75804b01a19b2d6e6101b445c1c68satok mostApplicableIMI = imi; 2192cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok mostApplicableSubtype = subtype; 21934e4569dab5c75804b01a19b2d6e6101b445c1c68satok break; 21944e4569dab5c75804b01a19b2d6e6101b445c1c68satok } else if (!foundInSystemIME) { 21957599a7fb1ab5b75ca801f7d7e448f4c097320e01satok // The system input method is 2nd applicable IME. 21964e4569dab5c75804b01a19b2d6e6101b445c1c68satok mostApplicableIMI = imi; 2197cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok mostApplicableSubtype = subtype; 21987599a7fb1ab5b75ca801f7d7e448f4c097320e01satok if ((imi.getServiceInfo().applicationInfo.flags 21997599a7fb1ab5b75ca801f7d7e448f4c097320e01satok & ApplicationInfo.FLAG_SYSTEM) != 0) { 22007599a7fb1ab5b75ca801f7d7e448f4c097320e01satok foundInSystemIME = true; 22017599a7fb1ab5b75ca801f7d7e448f4c097320e01satok } 22024e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 22034e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 22044e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 22054e4569dab5c75804b01a19b2d6e6101b445c1c68satok if (DEBUG) { 2206cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok if (mostApplicableIMI != null) { 2207cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok Slog.w(TAG, "Most applicable shortcut input method was:" 2208cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok + mostApplicableIMI.getId()); 2209cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok if (mostApplicableSubtype != null) { 2210cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok Slog.w(TAG, "Most applicable shortcut input method subtype was:" 2211cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok + "," + mostApplicableSubtype.getMode() + "," 2212cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok + mostApplicableSubtype.getLocale()); 2213cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok } 2214cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok } 22154e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 2216cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok if (mostApplicableIMI != null) { 22174e4569dab5c75804b01a19b2d6e6101b445c1c68satok return new Pair<InputMethodInfo, InputMethodSubtype> (mostApplicableIMI, 2218cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok mostApplicableSubtype); 22194e4569dab5c75804b01a19b2d6e6101b445c1c68satok } else { 22204e4569dab5c75804b01a19b2d6e6101b445c1c68satok return null; 22214e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 22224e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 22234e4569dab5c75804b01a19b2d6e6101b445c1c68satok 22244d733290a112fbe7ca5631ee870094b538f39d80satok private static long getSystemSettingsVersion() { 22254d733290a112fbe7ca5631ee870094b538f39d80satok return SystemProperties.getLong(Settings.Secure.SYS_PROP_SETTING_VERSION, 0); 22264d733290a112fbe7ca5631ee870094b538f39d80satok } 22274d733290a112fbe7ca5631ee870094b538f39d80satok 2228ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok /** 2229ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok * @return Return the current subtype of this input method. 2230ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok */ 2231ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok public InputMethodSubtype getCurrentInputMethodSubtype() { 22324e4569dab5c75804b01a19b2d6e6101b445c1c68satok boolean subtypeIsSelected = false; 22334e4569dab5c75804b01a19b2d6e6101b445c1c68satok try { 22344e4569dab5c75804b01a19b2d6e6101b445c1c68satok subtypeIsSelected = Settings.Secure.getInt(mContext.getContentResolver(), 22354e4569dab5c75804b01a19b2d6e6101b445c1c68satok Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE) != NOT_A_SUBTYPE_ID; 22364e4569dab5c75804b01a19b2d6e6101b445c1c68satok } catch (SettingNotFoundException e) { 22374e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 22383ef8b29fa03fe3ae1c57fd891a12afa46128fff8satok synchronized (mMethodMap) { 22393ef8b29fa03fe3ae1c57fd891a12afa46128fff8satok if (!subtypeIsSelected || mCurrentSubtype == null) { 22404e4569dab5c75804b01a19b2d6e6101b445c1c68satok String lastInputMethodId = Settings.Secure.getString( 22414e4569dab5c75804b01a19b2d6e6101b445c1c68satok mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD); 22423ef8b29fa03fe3ae1c57fd891a12afa46128fff8satok int subtypeId = getSelectedInputMethodSubtypeId(lastInputMethodId); 22433ef8b29fa03fe3ae1c57fd891a12afa46128fff8satok if (subtypeId == NOT_A_SUBTYPE_ID) { 22444e4569dab5c75804b01a19b2d6e6101b445c1c68satok InputMethodInfo imi = mMethodMap.get(lastInputMethodId); 22454e4569dab5c75804b01a19b2d6e6101b445c1c68satok if (imi != null) { 22464e4569dab5c75804b01a19b2d6e6101b445c1c68satok // If there are no selected subtypes, the framework will try to find 2247d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok // the most applicable subtype from explicitly or implicitly enabled 2248d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok // subtypes. 2249d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypes = 2250d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok getEnabledInputMethodSubtypeList(imi, true); 2251d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok // If there is only one explicitly or implicitly enabled subtype, 2252d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok // just returns it. 2253d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok if (explicitlyOrImplicitlyEnabledSubtypes.size() == 1) { 2254d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok mCurrentSubtype = explicitlyOrImplicitlyEnabledSubtypes.get(0); 2255d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok } else if (explicitlyOrImplicitlyEnabledSubtypes.size() > 1) { 2256d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok mCurrentSubtype = findLastResortApplicableSubtypeLocked( 2257d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok mRes, explicitlyOrImplicitlyEnabledSubtypes, 2258d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok SUBTYPE_MODE_KEYBOARD, null, true); 2259d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok if (mCurrentSubtype == null) { 2260d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok mCurrentSubtype = findLastResortApplicableSubtypeLocked( 2261d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok mRes, explicitlyOrImplicitlyEnabledSubtypes, null, null, 2262d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok true); 2263d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok } 2264d871343dbbde38f25ac0b41155e2f9d2dd7aadcasatok } 22654e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 2266cd7cd2969f545ad061a9b4ecd0044f15eb1b4abbsatok } else { 22673ef8b29fa03fe3ae1c57fd891a12afa46128fff8satok mCurrentSubtype = 2268586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa getSubtypes(mMethodMap.get(lastInputMethodId)).get(subtypeId); 22693ef8b29fa03fe3ae1c57fd891a12afa46128fff8satok } 22708fbb1e84ee6497f89322f2e40453c1cfa83fb4efsatok } 22713ef8b29fa03fe3ae1c57fd891a12afa46128fff8satok return mCurrentSubtype; 22728fbb1e84ee6497f89322f2e40453c1cfa83fb4efsatok } 2273ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok } 2274ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok 2275f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok private void addShortcutInputMethodAndSubtypes(InputMethodInfo imi, 2276f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok InputMethodSubtype subtype) { 2277f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok if (mShortcutInputMethodsAndSubtypes.containsKey(imi)) { 2278f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok mShortcutInputMethodsAndSubtypes.get(imi).add(subtype); 2279f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok } else { 2280f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>(); 2281f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok subtypes.add(subtype); 2282f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok mShortcutInputMethodsAndSubtypes.put(imi, subtypes); 2283f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok } 2284f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok } 2285f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok 22864e4569dab5c75804b01a19b2d6e6101b445c1c68satok // TODO: We should change the return type from List to List<Parcelable> 22874e4569dab5c75804b01a19b2d6e6101b445c1c68satok public List getShortcutInputMethodsAndSubtypes() { 22884e4569dab5c75804b01a19b2d6e6101b445c1c68satok synchronized (mMethodMap) { 22893da922367c0dbe67b97fe97fcfca13fd93602f7asatok ArrayList<Object> ret = new ArrayList<Object>(); 2290f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok if (mShortcutInputMethodsAndSubtypes.size() == 0) { 22914e4569dab5c75804b01a19b2d6e6101b445c1c68satok // If there are no selected shortcut subtypes, the framework will try to find 22924e4569dab5c75804b01a19b2d6e6101b445c1c68satok // the most applicable subtype from all subtypes whose mode is 22934e4569dab5c75804b01a19b2d6e6101b445c1c68satok // SUBTYPE_MODE_VOICE. This is an exceptional case, so we will hardcode the mode. 2294f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok Pair<InputMethodInfo, InputMethodSubtype> info = 2295f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok findLastResortApplicableShortcutInputMethodAndSubtypeLocked( 2296f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok SUBTYPE_MODE_VOICE); 22977599a7fb1ab5b75ca801f7d7e448f4c097320e01satok if (info != null) { 22983da922367c0dbe67b97fe97fcfca13fd93602f7asatok ret.add(info.first); 22993da922367c0dbe67b97fe97fcfca13fd93602f7asatok ret.add(info.second); 23007599a7fb1ab5b75ca801f7d7e448f4c097320e01satok } 23013da922367c0dbe67b97fe97fcfca13fd93602f7asatok return ret; 2302f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok } 2303f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok for (InputMethodInfo imi: mShortcutInputMethodsAndSubtypes.keySet()) { 2304f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok ret.add(imi); 2305f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok for (InputMethodSubtype subtype: mShortcutInputMethodsAndSubtypes.get(imi)) { 2306f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok ret.add(subtype); 23074e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 23084e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 2309f3db1af8d55ab247b6db67baf4fe772c18f33cabsatok return ret; 23104e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 23114e4569dab5c75804b01a19b2d6e6101b445c1c68satok } 23124e4569dab5c75804b01a19b2d6e6101b445c1c68satok 2313b66d287e3003a0934d5714fbf15e554b3c814906satok public boolean setCurrentInputMethodSubtype(InputMethodSubtype subtype) { 2314b66d287e3003a0934d5714fbf15e554b3c814906satok synchronized (mMethodMap) { 2315b66d287e3003a0934d5714fbf15e554b3c814906satok if (subtype != null && mCurMethodId != null) { 2316b66d287e3003a0934d5714fbf15e554b3c814906satok InputMethodInfo imi = mMethodMap.get(mCurMethodId); 2317b66d287e3003a0934d5714fbf15e554b3c814906satok int subtypeId = getSubtypeIdFromHashCode(imi, subtype.hashCode()); 2318b66d287e3003a0934d5714fbf15e554b3c814906satok if (subtypeId != NOT_A_SUBTYPE_ID) { 2319b66d287e3003a0934d5714fbf15e554b3c814906satok setInputMethodLocked(mCurMethodId, subtypeId); 2320b66d287e3003a0934d5714fbf15e554b3c814906satok return true; 2321b66d287e3003a0934d5714fbf15e554b3c814906satok } 2322b66d287e3003a0934d5714fbf15e554b3c814906satok } 2323b66d287e3003a0934d5714fbf15e554b3c814906satok return false; 2324b66d287e3003a0934d5714fbf15e554b3c814906satok } 2325b66d287e3003a0934d5714fbf15e554b3c814906satok } 2326b66d287e3003a0934d5714fbf15e554b3c814906satok 2327d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok /** 2328d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok * Utility class for putting and getting settings for InputMethod 2329d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok * TODO: Move all putters and getters of settings to this class. 2330d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok */ 2331d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok private static class InputMethodSettings { 2332d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // The string for enabled input method is saved as follows: 2333d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // example: ("ime0;subtype0;subtype1;subtype2:ime1:ime2;subtype0") 2334d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok private static final char INPUT_METHOD_SEPARATER = ':'; 2335d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok private static final char INPUT_METHOD_SUBTYPE_SEPARATER = ';'; 2336723a27ef3d7c94fc666abc52e0abd5e8526acb69satok private final TextUtils.SimpleStringSplitter mInputMethodSplitter = 2337d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok new TextUtils.SimpleStringSplitter(INPUT_METHOD_SEPARATER); 2338d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok 2339723a27ef3d7c94fc666abc52e0abd5e8526acb69satok private final TextUtils.SimpleStringSplitter mSubtypeSplitter = 2340d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok new TextUtils.SimpleStringSplitter(INPUT_METHOD_SUBTYPE_SEPARATER); 2341d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok 2342df31ae6a3011d47421a6ac10021f9649dc34a156satok private final Resources mRes; 2343d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok private final ContentResolver mResolver; 2344d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok private final HashMap<String, InputMethodInfo> mMethodMap; 2345d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok private final ArrayList<InputMethodInfo> mMethodList; 2346d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok 2347d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok private String mEnabledInputMethodsStrCache; 2348d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok 2349d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok private static void buildEnabledInputMethodsSettingString( 2350d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok StringBuilder builder, Pair<String, ArrayList<String>> pair) { 2351d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok String id = pair.first; 2352d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok ArrayList<String> subtypes = pair.second; 2353d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok builder.append(id); 235457c767c7b7a4cdcd0c33ec453a9f2c0b853999b6satok // Inputmethod and subtypes are saved in the settings as follows: 235557c767c7b7a4cdcd0c33ec453a9f2c0b853999b6satok // ime0;subtype0;subtype1:ime1;subtype0:ime2:ime3;subtype0;subtype1 235657c767c7b7a4cdcd0c33ec453a9f2c0b853999b6satok for (String subtypeId: subtypes) { 235757c767c7b7a4cdcd0c33ec453a9f2c0b853999b6satok builder.append(INPUT_METHOD_SUBTYPE_SEPARATER).append(subtypeId); 2358d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2359d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2360d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok 2361d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok public InputMethodSettings( 2362df31ae6a3011d47421a6ac10021f9649dc34a156satok Resources res, ContentResolver resolver, 2363df31ae6a3011d47421a6ac10021f9649dc34a156satok HashMap<String, InputMethodInfo> methodMap, ArrayList<InputMethodInfo> methodList) { 2364df31ae6a3011d47421a6ac10021f9649dc34a156satok mRes = res; 2365d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok mResolver = resolver; 2366d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok mMethodMap = methodMap; 2367d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok mMethodList = methodList; 2368d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2369d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok 2370d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok public List<InputMethodInfo> getEnabledInputMethodListLocked() { 2371d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok return createEnabledInputMethodListLocked( 2372d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok getEnabledInputMethodsAndSubtypeListLocked()); 2373d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2374d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok 23757f35c8cc88bea5230f001dd4356f864845d202e5satok public List<Pair<InputMethodInfo, ArrayList<String>>> 237667ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok getEnabledInputMethodAndSubtypeHashCodeListLocked() { 237767ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok return createEnabledInputMethodAndSubtypeHashCodeListLocked( 23787f35c8cc88bea5230f001dd4356f864845d202e5satok getEnabledInputMethodsAndSubtypeListLocked()); 23797f35c8cc88bea5230f001dd4356f864845d202e5satok } 23807f35c8cc88bea5230f001dd4356f864845d202e5satok 238167ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok public List<InputMethodSubtype> getEnabledInputMethodSubtypeListLocked( 238267ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok InputMethodInfo imi) { 238367ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok List<Pair<String, ArrayList<String>>> imsList = 238467ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok getEnabledInputMethodsAndSubtypeListLocked(); 238567ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok ArrayList<InputMethodSubtype> enabledSubtypes = 238667ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok new ArrayList<InputMethodSubtype>(); 2387884ef9a11fb25b80630265daee46c5609707751fsatok if (imi != null) { 2388884ef9a11fb25b80630265daee46c5609707751fsatok for (Pair<String, ArrayList<String>> imsPair : imsList) { 2389884ef9a11fb25b80630265daee46c5609707751fsatok InputMethodInfo info = mMethodMap.get(imsPair.first); 2390884ef9a11fb25b80630265daee46c5609707751fsatok if (info != null && info.getId().equals(imi.getId())) { 2391586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa final int subtypeCount = info.getSubtypeCount(); 2392586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa for (int i = 0; i < subtypeCount; ++i) { 2393586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa InputMethodSubtype ims = info.getSubtypeAt(i); 2394884ef9a11fb25b80630265daee46c5609707751fsatok for (String s: imsPair.second) { 2395884ef9a11fb25b80630265daee46c5609707751fsatok if (String.valueOf(ims.hashCode()).equals(s)) { 2396884ef9a11fb25b80630265daee46c5609707751fsatok enabledSubtypes.add(ims); 2397884ef9a11fb25b80630265daee46c5609707751fsatok } 239867ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok } 239967ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok } 2400884ef9a11fb25b80630265daee46c5609707751fsatok break; 240167ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok } 240267ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok } 240367ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok } 240467ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok return enabledSubtypes; 240567ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok } 240667ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok 2407d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // At the initial boot, the settings for input methods are not set, 2408d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // so we need to enable IME in that case. 2409d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok public void enableAllIMEsIfThereIsNoEnabledIME() { 2410d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok if (TextUtils.isEmpty(getEnabledInputMethodsStr())) { 2411d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok StringBuilder sb = new StringBuilder(); 2412d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok final int N = mMethodList.size(); 2413d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok for (int i = 0; i < N; i++) { 2414d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok InputMethodInfo imi = mMethodList.get(i); 2415d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok Slog.i(TAG, "Adding: " + imi.getId()); 2416d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok if (i > 0) sb.append(':'); 2417d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok sb.append(imi.getId()); 2418d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2419d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok putEnabledInputMethodsStr(sb.toString()); 2420d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2421d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2422d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok 2423bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok private List<Pair<String, ArrayList<String>>> getEnabledInputMethodsAndSubtypeListLocked() { 2424d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok ArrayList<Pair<String, ArrayList<String>>> imsList 2425d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok = new ArrayList<Pair<String, ArrayList<String>>>(); 2426d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok final String enabledInputMethodsStr = getEnabledInputMethodsStr(); 2427d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok if (TextUtils.isEmpty(enabledInputMethodsStr)) { 2428d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok return imsList; 2429d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2430723a27ef3d7c94fc666abc52e0abd5e8526acb69satok mInputMethodSplitter.setString(enabledInputMethodsStr); 2431723a27ef3d7c94fc666abc52e0abd5e8526acb69satok while (mInputMethodSplitter.hasNext()) { 2432723a27ef3d7c94fc666abc52e0abd5e8526acb69satok String nextImsStr = mInputMethodSplitter.next(); 2433723a27ef3d7c94fc666abc52e0abd5e8526acb69satok mSubtypeSplitter.setString(nextImsStr); 2434723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (mSubtypeSplitter.hasNext()) { 2435d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok ArrayList<String> subtypeHashes = new ArrayList<String>(); 2436d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // The first element is ime id. 2437723a27ef3d7c94fc666abc52e0abd5e8526acb69satok String imeId = mSubtypeSplitter.next(); 2438723a27ef3d7c94fc666abc52e0abd5e8526acb69satok while (mSubtypeSplitter.hasNext()) { 2439723a27ef3d7c94fc666abc52e0abd5e8526acb69satok subtypeHashes.add(mSubtypeSplitter.next()); 2440d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2441d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok imsList.add(new Pair<String, ArrayList<String>>(imeId, subtypeHashes)); 2442d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2443d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2444d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok return imsList; 2445d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2446d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok 2447d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok public void appendAndPutEnabledInputMethodLocked(String id, boolean reloadInputMethodStr) { 2448d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok if (reloadInputMethodStr) { 2449d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok getEnabledInputMethodsStr(); 2450d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2451d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok if (TextUtils.isEmpty(mEnabledInputMethodsStrCache)) { 2452d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // Add in the newly enabled input method. 2453d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok putEnabledInputMethodsStr(id); 2454d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } else { 2455d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok putEnabledInputMethodsStr( 2456d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok mEnabledInputMethodsStrCache + INPUT_METHOD_SEPARATER + id); 2457d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2458d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2459d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok 2460d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok /** 2461d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok * Build and put a string of EnabledInputMethods with removing specified Id. 2462d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok * @return the specified id was removed or not. 2463d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok */ 2464d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok public boolean buildAndPutEnabledInputMethodsStrRemovingIdLocked( 2465d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok StringBuilder builder, List<Pair<String, ArrayList<String>>> imsList, String id) { 2466d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok boolean isRemoved = false; 2467d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok boolean needsAppendSeparator = false; 2468d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok for (Pair<String, ArrayList<String>> ims: imsList) { 2469d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok String curId = ims.first; 2470d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok if (curId.equals(id)) { 2471d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // We are disabling this input method, and it is 2472d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // currently enabled. Skip it to remove from the 2473d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // new list. 2474d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok isRemoved = true; 2475d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } else { 2476d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok if (needsAppendSeparator) { 2477d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok builder.append(INPUT_METHOD_SEPARATER); 2478d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } else { 2479d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok needsAppendSeparator = true; 2480d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2481d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok buildEnabledInputMethodsSettingString(builder, ims); 2482d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2483d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2484d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok if (isRemoved) { 2485d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok // Update the setting with the new list of input methods. 2486d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok putEnabledInputMethodsStr(builder.toString()); 2487d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2488d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok return isRemoved; 2489d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2490d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok 2491d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok private List<InputMethodInfo> createEnabledInputMethodListLocked( 2492d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok List<Pair<String, ArrayList<String>>> imsList) { 2493d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok final ArrayList<InputMethodInfo> res = new ArrayList<InputMethodInfo>(); 2494d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok for (Pair<String, ArrayList<String>> ims: imsList) { 2495d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok InputMethodInfo info = mMethodMap.get(ims.first); 2496d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok if (info != null) { 2497d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok res.add(info); 2498d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2499d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2500d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok return res; 2501d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2502d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok 25037f35c8cc88bea5230f001dd4356f864845d202e5satok private List<Pair<InputMethodInfo, ArrayList<String>>> 250467ddf9cbd5d7133c7f443cd3c55841ed1109c3a0satok createEnabledInputMethodAndSubtypeHashCodeListLocked( 25057f35c8cc88bea5230f001dd4356f864845d202e5satok List<Pair<String, ArrayList<String>>> imsList) { 25067f35c8cc88bea5230f001dd4356f864845d202e5satok final ArrayList<Pair<InputMethodInfo, ArrayList<String>>> res 25077f35c8cc88bea5230f001dd4356f864845d202e5satok = new ArrayList<Pair<InputMethodInfo, ArrayList<String>>>(); 25087f35c8cc88bea5230f001dd4356f864845d202e5satok for (Pair<String, ArrayList<String>> ims : imsList) { 25097f35c8cc88bea5230f001dd4356f864845d202e5satok InputMethodInfo info = mMethodMap.get(ims.first); 25107f35c8cc88bea5230f001dd4356f864845d202e5satok if (info != null) { 25117f35c8cc88bea5230f001dd4356f864845d202e5satok res.add(new Pair<InputMethodInfo, ArrayList<String>>(info, ims.second)); 25127f35c8cc88bea5230f001dd4356f864845d202e5satok } 25137f35c8cc88bea5230f001dd4356f864845d202e5satok } 25147f35c8cc88bea5230f001dd4356f864845d202e5satok return res; 25157f35c8cc88bea5230f001dd4356f864845d202e5satok } 25167f35c8cc88bea5230f001dd4356f864845d202e5satok 2517d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok private void putEnabledInputMethodsStr(String str) { 2518d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok Settings.Secure.putString(mResolver, Settings.Secure.ENABLED_INPUT_METHODS, str); 2519d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok mEnabledInputMethodsStrCache = str; 2520d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2521d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok 2522d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok private String getEnabledInputMethodsStr() { 2523d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok mEnabledInputMethodsStrCache = Settings.Secure.getString( 2524d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok mResolver, Settings.Secure.ENABLED_INPUT_METHODS); 2525723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (DEBUG) { 2526723a27ef3d7c94fc666abc52e0abd5e8526acb69satok Slog.d(TAG, "getEnabledInputMethodsStr: " + mEnabledInputMethodsStrCache); 2527723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2528d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok return mEnabledInputMethodsStrCache; 2529d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2530723a27ef3d7c94fc666abc52e0abd5e8526acb69satok 2531723a27ef3d7c94fc666abc52e0abd5e8526acb69satok private void saveSubtypeHistory( 2532723a27ef3d7c94fc666abc52e0abd5e8526acb69satok List<Pair<String, String>> savedImes, String newImeId, String newSubtypeId) { 2533723a27ef3d7c94fc666abc52e0abd5e8526acb69satok StringBuilder builder = new StringBuilder(); 2534723a27ef3d7c94fc666abc52e0abd5e8526acb69satok boolean isImeAdded = false; 2535723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (!TextUtils.isEmpty(newImeId) && !TextUtils.isEmpty(newSubtypeId)) { 2536723a27ef3d7c94fc666abc52e0abd5e8526acb69satok builder.append(newImeId).append(INPUT_METHOD_SUBTYPE_SEPARATER).append( 2537723a27ef3d7c94fc666abc52e0abd5e8526acb69satok newSubtypeId); 2538723a27ef3d7c94fc666abc52e0abd5e8526acb69satok isImeAdded = true; 2539723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2540723a27ef3d7c94fc666abc52e0abd5e8526acb69satok for (Pair<String, String> ime: savedImes) { 2541723a27ef3d7c94fc666abc52e0abd5e8526acb69satok String imeId = ime.first; 2542723a27ef3d7c94fc666abc52e0abd5e8526acb69satok String subtypeId = ime.second; 2543723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (TextUtils.isEmpty(subtypeId)) { 2544723a27ef3d7c94fc666abc52e0abd5e8526acb69satok subtypeId = NOT_A_SUBTYPE_ID_STR; 2545723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2546723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (isImeAdded) { 2547723a27ef3d7c94fc666abc52e0abd5e8526acb69satok builder.append(INPUT_METHOD_SEPARATER); 2548723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } else { 2549723a27ef3d7c94fc666abc52e0abd5e8526acb69satok isImeAdded = true; 2550723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2551723a27ef3d7c94fc666abc52e0abd5e8526acb69satok builder.append(imeId).append(INPUT_METHOD_SUBTYPE_SEPARATER).append( 2552723a27ef3d7c94fc666abc52e0abd5e8526acb69satok subtypeId); 2553723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2554723a27ef3d7c94fc666abc52e0abd5e8526acb69satok // Remove the last INPUT_METHOD_SEPARATER 2555723a27ef3d7c94fc666abc52e0abd5e8526acb69satok putSubtypeHistoryStr(builder.toString()); 2556723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2557723a27ef3d7c94fc666abc52e0abd5e8526acb69satok 2558723a27ef3d7c94fc666abc52e0abd5e8526acb69satok public void addSubtypeToHistory(String imeId, String subtypeId) { 2559723a27ef3d7c94fc666abc52e0abd5e8526acb69satok List<Pair<String, String>> subtypeHistory = loadInputMethodAndSubtypeHistoryLocked(); 2560723a27ef3d7c94fc666abc52e0abd5e8526acb69satok for (Pair<String, String> ime: subtypeHistory) { 2561723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (ime.first.equals(imeId)) { 2562723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (DEBUG) { 2563bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok Slog.v(TAG, "Subtype found in the history: " + imeId + ", " 2564723a27ef3d7c94fc666abc52e0abd5e8526acb69satok + ime.second); 2565723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2566723a27ef3d7c94fc666abc52e0abd5e8526acb69satok // We should break here 2567723a27ef3d7c94fc666abc52e0abd5e8526acb69satok subtypeHistory.remove(ime); 2568723a27ef3d7c94fc666abc52e0abd5e8526acb69satok break; 2569723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2570723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2571bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok if (DEBUG) { 2572bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok Slog.v(TAG, "Add subtype to the history: " + imeId + ", " + subtypeId); 2573bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok } 2574723a27ef3d7c94fc666abc52e0abd5e8526acb69satok saveSubtypeHistory(subtypeHistory, imeId, subtypeId); 2575723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2576723a27ef3d7c94fc666abc52e0abd5e8526acb69satok 2577723a27ef3d7c94fc666abc52e0abd5e8526acb69satok private void putSubtypeHistoryStr(String str) { 2578723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (DEBUG) { 2579723a27ef3d7c94fc666abc52e0abd5e8526acb69satok Slog.d(TAG, "putSubtypeHistoryStr: " + str); 2580723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2581723a27ef3d7c94fc666abc52e0abd5e8526acb69satok Settings.Secure.putString( 2582723a27ef3d7c94fc666abc52e0abd5e8526acb69satok mResolver, Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY, str); 2583723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2584723a27ef3d7c94fc666abc52e0abd5e8526acb69satok 2585723a27ef3d7c94fc666abc52e0abd5e8526acb69satok public Pair<String, String> getLastInputMethodAndSubtypeLocked() { 2586723a27ef3d7c94fc666abc52e0abd5e8526acb69satok // Gets the first one from the history 2587723a27ef3d7c94fc666abc52e0abd5e8526acb69satok return getLastSubtypeForInputMethodLockedInternal(null); 2588723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2589723a27ef3d7c94fc666abc52e0abd5e8526acb69satok 2590723a27ef3d7c94fc666abc52e0abd5e8526acb69satok public String getLastSubtypeForInputMethodLocked(String imeId) { 2591723a27ef3d7c94fc666abc52e0abd5e8526acb69satok Pair<String, String> ime = getLastSubtypeForInputMethodLockedInternal(imeId); 2592723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (ime != null) { 2593723a27ef3d7c94fc666abc52e0abd5e8526acb69satok return ime.second; 2594723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } else { 2595723a27ef3d7c94fc666abc52e0abd5e8526acb69satok return null; 2596723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2597723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2598723a27ef3d7c94fc666abc52e0abd5e8526acb69satok 2599723a27ef3d7c94fc666abc52e0abd5e8526acb69satok private Pair<String, String> getLastSubtypeForInputMethodLockedInternal(String imeId) { 2600723a27ef3d7c94fc666abc52e0abd5e8526acb69satok List<Pair<String, ArrayList<String>>> enabledImes = 2601723a27ef3d7c94fc666abc52e0abd5e8526acb69satok getEnabledInputMethodsAndSubtypeListLocked(); 2602723a27ef3d7c94fc666abc52e0abd5e8526acb69satok List<Pair<String, String>> subtypeHistory = loadInputMethodAndSubtypeHistoryLocked(); 2603723a27ef3d7c94fc666abc52e0abd5e8526acb69satok for (Pair<String, String> imeAndSubtype: subtypeHistory) { 2604723a27ef3d7c94fc666abc52e0abd5e8526acb69satok final String imeInTheHistory = imeAndSubtype.first; 2605723a27ef3d7c94fc666abc52e0abd5e8526acb69satok // If imeId is empty, returns the first IME and subtype in the history 2606723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (TextUtils.isEmpty(imeId) || imeInTheHistory.equals(imeId)) { 2607723a27ef3d7c94fc666abc52e0abd5e8526acb69satok final String subtypeInTheHistory = imeAndSubtype.second; 2608df31ae6a3011d47421a6ac10021f9649dc34a156satok final String subtypeHashCode = 2609df31ae6a3011d47421a6ac10021f9649dc34a156satok getEnabledSubtypeHashCodeForInputMethodAndSubtypeLocked( 2610df31ae6a3011d47421a6ac10021f9649dc34a156satok enabledImes, imeInTheHistory, subtypeInTheHistory); 2611723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (!TextUtils.isEmpty(subtypeHashCode)) { 2612723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (DEBUG) { 2613bb4aa0683c8a0a1e617c6d5f03eda33f49b89ed9satok Slog.d(TAG, "Enabled subtype found in the history: " + subtypeHashCode); 2614723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2615723a27ef3d7c94fc666abc52e0abd5e8526acb69satok return new Pair<String, String>(imeInTheHistory, subtypeHashCode); 2616723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2617723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2618723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2619723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (DEBUG) { 2620723a27ef3d7c94fc666abc52e0abd5e8526acb69satok Slog.d(TAG, "No enabled IME found in the history"); 2621723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2622723a27ef3d7c94fc666abc52e0abd5e8526acb69satok return null; 2623723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2624723a27ef3d7c94fc666abc52e0abd5e8526acb69satok 2625df31ae6a3011d47421a6ac10021f9649dc34a156satok private String getEnabledSubtypeHashCodeForInputMethodAndSubtypeLocked(List<Pair<String, 2626723a27ef3d7c94fc666abc52e0abd5e8526acb69satok ArrayList<String>>> enabledImes, String imeId, String subtypeHashCode) { 2627723a27ef3d7c94fc666abc52e0abd5e8526acb69satok for (Pair<String, ArrayList<String>> enabledIme: enabledImes) { 2628723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (enabledIme.first.equals(imeId)) { 2629f6cafb63753a26440cb3ad2e5124370aef650015satok final ArrayList<String> explicitlyEnabledSubtypes = enabledIme.second; 2630f6cafb63753a26440cb3ad2e5124370aef650015satok if (explicitlyEnabledSubtypes.size() == 0) { 2631f6cafb63753a26440cb3ad2e5124370aef650015satok // If there are no explicitly enabled subtypes, applicable subtypes are 2632f6cafb63753a26440cb3ad2e5124370aef650015satok // enabled implicitly. 2633df31ae6a3011d47421a6ac10021f9649dc34a156satok InputMethodInfo ime = mMethodMap.get(imeId); 2634df31ae6a3011d47421a6ac10021f9649dc34a156satok // If IME is enabled and no subtypes are enabled, applicable subtypes 2635df31ae6a3011d47421a6ac10021f9649dc34a156satok // are enabled implicitly, so needs to treat them to be enabled. 2636586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa if (ime != null && ime.getSubtypeCount() > 0) { 2637df31ae6a3011d47421a6ac10021f9649dc34a156satok List<InputMethodSubtype> implicitlySelectedSubtypes = 2638586f051375d8d7aeece05329921f9f66fc6164cbKen Wakasa getApplicableSubtypesLocked(mRes, getSubtypes(ime)); 2639df31ae6a3011d47421a6ac10021f9649dc34a156satok if (implicitlySelectedSubtypes != null) { 2640df31ae6a3011d47421a6ac10021f9649dc34a156satok final int N = implicitlySelectedSubtypes.size(); 2641df31ae6a3011d47421a6ac10021f9649dc34a156satok for (int i = 0; i < N; ++i) { 2642df31ae6a3011d47421a6ac10021f9649dc34a156satok final InputMethodSubtype st = implicitlySelectedSubtypes.get(i); 2643df31ae6a3011d47421a6ac10021f9649dc34a156satok if (String.valueOf(st.hashCode()).equals(subtypeHashCode)) { 2644df31ae6a3011d47421a6ac10021f9649dc34a156satok return subtypeHashCode; 2645df31ae6a3011d47421a6ac10021f9649dc34a156satok } 2646df31ae6a3011d47421a6ac10021f9649dc34a156satok } 2647df31ae6a3011d47421a6ac10021f9649dc34a156satok } 2648df31ae6a3011d47421a6ac10021f9649dc34a156satok } 2649df31ae6a3011d47421a6ac10021f9649dc34a156satok } else { 2650f6cafb63753a26440cb3ad2e5124370aef650015satok for (String s: explicitlyEnabledSubtypes) { 2651df31ae6a3011d47421a6ac10021f9649dc34a156satok if (s.equals(subtypeHashCode)) { 2652df31ae6a3011d47421a6ac10021f9649dc34a156satok // If both imeId and subtypeId are enabled, return subtypeId. 2653df31ae6a3011d47421a6ac10021f9649dc34a156satok return s; 2654df31ae6a3011d47421a6ac10021f9649dc34a156satok } 2655723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2656723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2657723a27ef3d7c94fc666abc52e0abd5e8526acb69satok // If imeId was enabled but subtypeId was disabled. 2658723a27ef3d7c94fc666abc52e0abd5e8526acb69satok return NOT_A_SUBTYPE_ID_STR; 2659723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2660723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2661723a27ef3d7c94fc666abc52e0abd5e8526acb69satok // If both imeId and subtypeId are disabled, return null 2662723a27ef3d7c94fc666abc52e0abd5e8526acb69satok return null; 2663723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2664723a27ef3d7c94fc666abc52e0abd5e8526acb69satok 2665723a27ef3d7c94fc666abc52e0abd5e8526acb69satok private List<Pair<String, String>> loadInputMethodAndSubtypeHistoryLocked() { 2666723a27ef3d7c94fc666abc52e0abd5e8526acb69satok ArrayList<Pair<String, String>> imsList = new ArrayList<Pair<String, String>>(); 2667723a27ef3d7c94fc666abc52e0abd5e8526acb69satok final String subtypeHistoryStr = getSubtypeHistoryStr(); 2668723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (TextUtils.isEmpty(subtypeHistoryStr)) { 2669723a27ef3d7c94fc666abc52e0abd5e8526acb69satok return imsList; 2670723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2671723a27ef3d7c94fc666abc52e0abd5e8526acb69satok mInputMethodSplitter.setString(subtypeHistoryStr); 2672723a27ef3d7c94fc666abc52e0abd5e8526acb69satok while (mInputMethodSplitter.hasNext()) { 2673723a27ef3d7c94fc666abc52e0abd5e8526acb69satok String nextImsStr = mInputMethodSplitter.next(); 2674723a27ef3d7c94fc666abc52e0abd5e8526acb69satok mSubtypeSplitter.setString(nextImsStr); 2675723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (mSubtypeSplitter.hasNext()) { 2676723a27ef3d7c94fc666abc52e0abd5e8526acb69satok String subtypeId = NOT_A_SUBTYPE_ID_STR; 2677723a27ef3d7c94fc666abc52e0abd5e8526acb69satok // The first element is ime id. 2678723a27ef3d7c94fc666abc52e0abd5e8526acb69satok String imeId = mSubtypeSplitter.next(); 2679723a27ef3d7c94fc666abc52e0abd5e8526acb69satok while (mSubtypeSplitter.hasNext()) { 2680723a27ef3d7c94fc666abc52e0abd5e8526acb69satok subtypeId = mSubtypeSplitter.next(); 2681723a27ef3d7c94fc666abc52e0abd5e8526acb69satok break; 2682723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2683723a27ef3d7c94fc666abc52e0abd5e8526acb69satok imsList.add(new Pair<String, String>(imeId, subtypeId)); 2684723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2685723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2686723a27ef3d7c94fc666abc52e0abd5e8526acb69satok return imsList; 2687723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2688723a27ef3d7c94fc666abc52e0abd5e8526acb69satok 2689723a27ef3d7c94fc666abc52e0abd5e8526acb69satok private String getSubtypeHistoryStr() { 2690723a27ef3d7c94fc666abc52e0abd5e8526acb69satok if (DEBUG) { 2691723a27ef3d7c94fc666abc52e0abd5e8526acb69satok Slog.d(TAG, "getSubtypeHistoryStr: " + Settings.Secure.getString( 2692723a27ef3d7c94fc666abc52e0abd5e8526acb69satok mResolver, Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY)); 2693723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2694723a27ef3d7c94fc666abc52e0abd5e8526acb69satok return Settings.Secure.getString( 2695723a27ef3d7c94fc666abc52e0abd5e8526acb69satok mResolver, Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY); 2696723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2697723a27ef3d7c94fc666abc52e0abd5e8526acb69satok 2698723a27ef3d7c94fc666abc52e0abd5e8526acb69satok public void putSelectedInputMethod(String imeId) { 2699723a27ef3d7c94fc666abc52e0abd5e8526acb69satok Settings.Secure.putString(mResolver, Settings.Secure.DEFAULT_INPUT_METHOD, imeId); 2700723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2701723a27ef3d7c94fc666abc52e0abd5e8526acb69satok 2702723a27ef3d7c94fc666abc52e0abd5e8526acb69satok public void putSelectedSubtype(int subtypeId) { 2703723a27ef3d7c94fc666abc52e0abd5e8526acb69satok Settings.Secure.putInt( 2704723a27ef3d7c94fc666abc52e0abd5e8526acb69satok mResolver, Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, subtypeId); 2705723a27ef3d7c94fc666abc52e0abd5e8526acb69satok } 2706d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok } 2707d87c2594c688b4ed8fc9c14053abfbc5ea87fb5esatok 27089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ---------------------------------------------------------------------- 2709ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 27109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 27119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 27129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 27139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 2714ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 27159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Permission Denial: can't dump InputMethodManager from from pid=" 27169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Binder.getCallingPid() 27179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", uid=" + Binder.getCallingUid()); 27189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 27199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IInputMethod method; 27229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ClientState client; 2723ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 27249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Printer p = new PrintWriterPrinter(pw); 2725ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 27269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mMethodMap) { 27279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println("Current Input Method Manager state:"); 27289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int N = mMethodList.size(); 27299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" Input Methods:"); 27309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 27319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputMethodInfo info = mMethodList.get(i); 27329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" InputMethod #" + i + ":"); 27339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project info.dump(p, " "); 27349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" Clients:"); 27369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (ClientState ci : mClients.values()) { 27379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" Client " + ci + ":"); 27389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" client=" + ci.client); 27399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" inputContext=" + ci.inputContext); 27409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" sessionRequested=" + ci.sessionRequested); 27419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" curSession=" + ci.curSession); 27429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2743105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project p.println(" mCurMethodId=" + mCurMethodId); 27449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project client = mCurClient; 2745b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project p.println(" mCurClient=" + client + " mCurSeq=" + mCurSeq); 2746b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project p.println(" mCurFocusedWindow=" + mCurFocusedWindow); 27479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mCurId=" + mCurId + " mHaveConnect=" + mHaveConnection 27489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " mBoundToMethod=" + mBoundToMethod); 27499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mCurToken=" + mCurToken); 27509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mCurIntent=" + mCurIntent); 27519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project method = mCurMethod; 27529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mCurMethod=" + mCurMethod); 27539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mEnabledSession=" + mEnabledSession); 27549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println(" mShowRequested=" + mShowRequested 27559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " mShowExplicitlyRequested=" + mShowExplicitlyRequested 27569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " mShowForced=" + mShowForced 27579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " mInputShown=" + mInputShown); 2758cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn p.println(" mSystemReady=" + mSystemReady + " mScreenOn=" + mScreenOn); 27599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2760ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 2761b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown p.println(" "); 27629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (client != null) { 27639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.flush(); 27649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 27659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project client.client.asBinder().dump(fd, args); 27669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 27679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println("Input method client dead: " + e); 27689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2769b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown } else { 2770b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown p.println("No input method client."); 27719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2772ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker 2773b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown p.println(" "); 27749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (method != null) { 27759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.flush(); 27769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 27779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project method.asBinder().dump(fd, args); 27789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 27799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.println("Input method service dead: " + e); 27809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2781b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown } else { 2782b88102f5b7e51552a3576cf197b4c8cf96f193d1Jeff Brown p.println("No input method service."); 27839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 27859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2786