InputMethodManagerService.java revision e861ec11c458b4f76eb80da518dfee6a400071bf
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
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.server.status.IconData;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.server.status.StatusBarService;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException;
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.ActivityManagerNative;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.AlertDialog;
36dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackbornimport android.app.PendingIntent;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ComponentName;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.DialogInterface;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.IntentFilter;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.DialogInterface.OnCancelListener;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ServiceConnection;
456da35a0c1205398b7df4776e359f7794584fb128Brandon Ballingerimport android.content.pm.ApplicationInfo;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.ResolveInfo;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.ServiceInfo;
49e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasaniimport android.content.res.Configuration;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.database.ContentObserver;
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;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings;
64e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasaniimport android.provider.Settings.Secure;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.EventLog;
678a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.PrintWriterPrinter;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Printer;
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.IWindowManager;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.WindowManager;
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputBinding;
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethod;
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethodInfo;
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethodManager;
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.EditorInfo;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor;
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class provides a system service that manages input methods.
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class InputMethodManagerService extends IInputMethodManager.Stub
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        implements ServiceConnection, Handler.Callback {
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final boolean DEBUG = false;
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final String TAG = "InputManagerService";
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MSG_SHOW_IM_PICKER = 1;
94ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MSG_UNBIND_INPUT = 1000;
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MSG_BIND_INPUT = 1010;
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MSG_SHOW_SOFT_INPUT = 1020;
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MSG_HIDE_SOFT_INPUT = 1030;
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MSG_ATTACH_TOKEN = 1040;
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MSG_CREATE_SESSION = 1050;
101ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MSG_START_INPUT = 2000;
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MSG_RESTART_INPUT = 2010;
104ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MSG_UNBIND_METHOD = 3000;
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final int MSG_BIND_METHOD = 3010;
107ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static final long TIME_TO_RECONNECT = 10*1000;
109ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final Context mContext;
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final Handler mHandler;
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final SettingsObserver mSettingsObserver;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final StatusBarService mStatusBar;
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final IBinder mInputMethodIcon;
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final IconData mInputMethodData;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final IWindowManager mIWindowManager;
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final HandlerCaller mCaller;
118ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final InputBindResult mNoBinding = new InputBindResult(null, null, -1);
120ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // All known input methods.  mMethodMap also serves as the global
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // lock for this class.
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final ArrayList<InputMethodInfo> mMethodList
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            = new ArrayList<InputMethodInfo>();
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final HashMap<String, InputMethodInfo> mMethodMap
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            = new HashMap<String, InputMethodInfo>();
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final TextUtils.SimpleStringSplitter mStringColonSplitter
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            = new TextUtils.SimpleStringSplitter(':');
130ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    class SessionState {
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ClientState client;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final IInputMethod method;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final IInputMethodSession session;
135ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String toString() {
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "SessionState{uid " + client.uid + " pid " + client.pid
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " method " + Integer.toHexString(
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            System.identityHashCode(method))
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " session " + Integer.toHexString(
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            System.identityHashCode(session))
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + "}";
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SessionState(ClientState _client, IInputMethod _method,
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                IInputMethodSession _session) {
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            client = _client;
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            method = _method;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            session = _session;
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
153ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    class ClientState {
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final IInputMethodClient client;
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final IInputContext inputContext;
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int uid;
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final int pid;
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final InputBinding binding;
160ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean sessionRequested;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SessionState curSession;
163ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public String toString() {
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return "ClientState{" + Integer.toHexString(
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    System.identityHashCode(this)) + " uid " + uid
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " pid " + pid + "}";
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ClientState(IInputMethodClient _client, IInputContext _inputContext,
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int _uid, int _pid) {
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            client = _client;
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            inputContext = _inputContext;
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            uid = _uid;
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pid = _pid;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            binding = new InputBinding(null, inputContext.asBinder(), uid, pid);
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
180ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final HashMap<IBinder, ClientState> mClients
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            = new HashMap<IBinder, ClientState>();
183ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
185a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn     * Set once the system is ready to run third party code.
186a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn     */
187a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn    boolean mSystemReady;
188ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
189a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn    /**
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Id of the currently selected input method.
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String mCurMethodId;
193ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The current binding sequence number, incremented every time there is
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a new bind performed.
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int mCurSeq;
199ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The client that is currently bound to an input method.
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ClientState mCurClient;
204ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
206b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     * The last window token that gained focus.
207b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project     */
208b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    IBinder mCurFocusedWindow;
209ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
210b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    /**
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The input context last provided by the current client.
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IInputContext mCurInputContext;
214ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The attributes last provided by the current client.
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    EditorInfo mCurAttribute;
219ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The input method ID of the input method service that we are currently
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * connected to or in the process of connecting to.
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String mCurId;
225ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set to true if our ServiceConnection is currently actively bound to
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a service (whether or not we have gotten its IBinder back yet).
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mHaveConnection;
231ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set if the client has asked for the input method to be shown.
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mShowRequested;
236ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set if we were explicitly told to show the input method.
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mShowExplicitlyRequested;
241ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set if we were forced to be shown.
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mShowForced;
246ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set if we last told the input method to show itself.
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mInputShown;
251ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The Intent used to connect to the current input method.
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    Intent mCurIntent;
256ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The token we have made for the currently active input method, to
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * identify it in the future.
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IBinder mCurToken;
262ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If non-null, this is the input method service we are currently connected
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to.
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    IInputMethod mCurMethod;
268ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Time that we last initiated a bind to the input method, to determine
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if we should try to disconnect and reconnect to it.
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    long mLastBindTime;
274ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Have we called mCurMethod.bindInput()?
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mBoundToMethod;
279ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Currently enabled session.  Only touched by service thread, not
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * protected by a lock.
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SessionState mEnabledSession;
285ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * True if the screen is on.  The value is true initially.
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boolean mScreenOn = true;
290ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    AlertDialog.Builder mDialogBuilder;
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    AlertDialog mSwitchingDialog;
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    InputMethodInfo[] mIms;
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    CharSequence[] mItems;
295ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    class SettingsObserver extends ContentObserver {
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        SettingsObserver(Handler handler) {
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(handler);
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ContentResolver resolver = mContext.getContentResolver();
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            resolver.registerContentObserver(Settings.Secure.getUriFor(
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Settings.Secure.DEFAULT_INPUT_METHOD), false, this);
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
303ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override public void onChange(boolean selfChange) {
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (mMethodMap) {
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                updateFromSettingsLocked();
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
310ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    class ScreenOnOffReceiver extends android.content.BroadcastReceiver {
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onReceive(Context context, Intent intent) {
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mScreenOn = true;
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mScreenOn = false;
318105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            } else if (intent.getAction().equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
319105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                hideInputMethodMenu();
320105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                return;
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
3228a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.w(TAG, "Unexpected intent " + intent);
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Inform the current client of the change in active status
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mCurClient != null && mCurClient.client != null) {
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCurClient.client.setActive(mScreenOn);
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException e) {
3318a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.w(TAG, "Got RemoteException sending 'screen on/off' notification to pid "
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + mCurClient.pid + " uid " + mCurClient.uid);
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
336ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
33721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    class MyPackageMonitor extends PackageMonitor {
33821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        @Override
34021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
34121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            synchronized (mMethodMap) {
34221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                String curInputMethodId = Settings.Secure.getString(mContext
34321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
34421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                final int N = mMethodList.size();
34521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                if (curInputMethodId != null) {
34621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    for (int i=0; i<N; i++) {
34721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        InputMethodInfo imi = mMethodList.get(i);
34821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        if (imi.getId().equals(curInputMethodId)) {
34921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                            for (String pkg : packages) {
35021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                if (imi.getPackageName().equals(pkg)) {
35121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                    if (!doit) {
35221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                        return true;
35321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                    }
35421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
35521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                    Settings.Secure.putString(mContext.getContentResolver(),
35621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                            Settings.Secure.DEFAULT_INPUT_METHOD, "");
35721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                    chooseNewDefaultIMELocked();
35821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                    return true;
35921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                }
36021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                            }
36121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        }
36221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    }
36308675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                }
36408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu            }
36521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            return false;
36621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
367ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
36821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        @Override
36921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        public void onSomePackagesChanged() {
37021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            synchronized (mMethodMap) {
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                InputMethodInfo curIm = null;
37221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                String curInputMethodId = Settings.Secure.getString(mContext
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                final int N = mMethodList.size();
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (curInputMethodId != null) {
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    for (int i=0; i<N; i++) {
37721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        InputMethodInfo imi = mMethodList.get(i);
37821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        if (imi.getId().equals(curInputMethodId)) {
37921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                            curIm = imi;
38021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        }
38121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        int change = isPackageDisappearing(imi.getPackageName());
38221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        if (change == PACKAGE_TEMPORARY_CHANGE
38321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                || change == PACKAGE_PERMANENT_CHANGE) {
3848a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                            Slog.i(TAG, "Input method uninstalled, disabling: "
38521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                                    + imi.getComponent());
38621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                            setInputMethodEnabledLocked(imi.getId(), false);
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
390ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
39121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                buildInputMethodListLocked(mMethodList, mMethodMap);
39221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                boolean changed = false;
394ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
39508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                if (curIm != null) {
39621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    int change = isPackageDisappearing(curIm.getPackageName());
39721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    if (change == PACKAGE_TEMPORARY_CHANGE
39821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                            || change == PACKAGE_PERMANENT_CHANGE) {
39908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                        ServiceInfo si = null;
40008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                        try {
40108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                            si = mContext.getPackageManager().getServiceInfo(
40208675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                                    curIm.getComponent(), 0);
40308675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                        } catch (PackageManager.NameNotFoundException ex) {
40408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                        }
40508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                        if (si == null) {
40608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                            // Uh oh, current input method is no longer around!
40708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                            // Pick another one...
4088a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                            Slog.i(TAG, "Current input method removed: " + curInputMethodId);
40921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                            if (!chooseNewDefaultIMELocked()) {
41008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                                changed = true;
41108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                                curIm = null;
41208675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                                curInputMethodId = "";
4138a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                                Slog.i(TAG, "Unsetting current input method");
41408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                                Settings.Secure.putString(mContext.getContentResolver(),
41508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                                        Settings.Secure.DEFAULT_INPUT_METHOD,
41608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                                        curInputMethodId);
41708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                            }
41808675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                        }
41908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu                    }
42021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
42121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
42221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                if (curIm == null) {
42321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    // We currently don't have a default input method... is
42421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    // one now available?
42521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    changed = chooseNewDefaultIMELocked();
42621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                }
427ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
42821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                if (changed) {
42921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    updateFromSettingsLocked();
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
434ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    class MethodCallback extends IInputMethodCallback.Stub {
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final IInputMethod mMethod;
437ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        MethodCallback(IInputMethod method) {
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mMethod = method;
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
441ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void finishedEvent(int seq, boolean handled) throws RemoteException {
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void sessionCreated(IInputMethodSession session) throws RemoteException {
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            onSessionCreated(mMethod, session);
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
449ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public InputMethodManagerService(Context context, StatusBarService statusBar) {
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler = new Handler(this);
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mIWindowManager = IWindowManager.Stub.asInterface(
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ServiceManager.getService(Context.WINDOW_SERVICE));
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller = new HandlerCaller(context, new HandlerCaller.Callback() {
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            public void executeMessage(Message msg) {
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                handleMessage(msg);
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        });
460ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
46121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        (new MyPackageMonitor()).register(mContext, true);
462ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IntentFilter screenOnOffFilt = new IntentFilter();
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        screenOnOffFilt.addAction(Intent.ACTION_SCREEN_ON);
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        screenOnOffFilt.addAction(Intent.ACTION_SCREEN_OFF);
466105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        screenOnOffFilt.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext.registerReceiver(new ScreenOnOffReceiver(), screenOnOffFilt);
468ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        buildInputMethodListLocked(mMethodList, mMethodMap);
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final String enabledStr = Settings.Secure.getString(
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mContext.getContentResolver(),
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Settings.Secure.ENABLED_INPUT_METHODS);
4748a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        Slog.i(TAG, "Enabled input methods: " + enabledStr);
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (enabledStr == null) {
4768a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.i(TAG, "Enabled input methods has not been set, enabling all");
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputMethodInfo defIm = null;
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            StringBuilder sb = new StringBuilder(256);
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final int N = mMethodList.size();
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i=0; i<N; i++) {
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                InputMethodInfo imi = mMethodList.get(i);
4828a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.i(TAG, "Adding: " + imi.getId());
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (i > 0) sb.append(':');
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sb.append(imi.getId());
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (defIm == null && imi.getIsDefaultResourceId() != 0) {
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    try {
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        Resources res = mContext.createPackageContext(
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                imi.getPackageName(), 0).getResources();
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (res.getBoolean(imi.getIsDefaultResourceId())) {
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            defIm = imi;
4918a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                            Slog.i(TAG, "Selected default: " + imi.getId());
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } catch (PackageManager.NameNotFoundException ex) {
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } catch (Resources.NotFoundException ex) {
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (defIm == null && N > 0) {
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                defIm = mMethodList.get(0);
5008a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.i(TAG, "No default found, using " + defIm.getId());
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Settings.Secure.putString(mContext.getContentResolver(),
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Settings.Secure.ENABLED_INPUT_METHODS, sb.toString());
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (defIm != null) {
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Settings.Secure.putString(mContext.getContentResolver(),
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        Settings.Secure.DEFAULT_INPUT_METHOD, defIm.getId());
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
509ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStatusBar = statusBar;
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputMethodData = IconData.makeIcon("ime", null, 0, 0, 0);
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputMethodIcon = statusBar.addIcon(mInputMethodData, null);
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        statusBar.setIconVisibility(mInputMethodIcon, false);
514ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mSettingsObserver = new SettingsObserver(mHandler);
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        updateFromSettingsLocked();
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws RemoteException {
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return super.onTransact(code, data, reply, flags);
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RuntimeException e) {
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // The input method manager only throws security exceptions, so let's
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // log all others.
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!(e instanceof SecurityException)) {
5288a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.e(TAG, "Input Method Manager Crash", e);
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw e;
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void systemReady() {
535a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn        synchronized (mMethodMap) {
536a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn            if (!mSystemReady) {
537a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn                mSystemReady = true;
538cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn                try {
539cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn                    startInputInnerLocked();
540cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn                } catch (RuntimeException e) {
5418a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.w(TAG, "Unexpected exception", e);
542cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn                }
543a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn            }
544a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn        }
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
546ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public List<InputMethodInfo> getInputMethodList() {
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mMethodMap) {
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new ArrayList<InputMethodInfo>(mMethodList);
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public List<InputMethodInfo> getEnabledInputMethodList() {
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mMethodMap) {
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return getEnabledInputMethodListLocked();
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    List<InputMethodInfo> getEnabledInputMethodListLocked() {
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final ArrayList<InputMethodInfo> res = new ArrayList<InputMethodInfo>();
561ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final String enabledStr = Settings.Secure.getString(
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mContext.getContentResolver(),
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Settings.Secure.ENABLED_INPUT_METHODS);
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (enabledStr != null) {
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            splitter.setString(enabledStr);
568ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            while (splitter.hasNext()) {
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                InputMethodInfo info = mMethodMap.get(splitter.next());
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (info != null) {
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    res.add(info);
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
576ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return res;
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void addClient(IInputMethodClient client,
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            IInputContext inputContext, int uid, int pid) {
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mMethodMap) {
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mClients.put(client.asBinder(), new ClientState(client,
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    inputContext, uid, pid));
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
587ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void removeClient(IInputMethodClient client) {
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mMethodMap) {
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mClients.remove(client.asBinder());
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
593ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void executeOrSendMessage(IInterface target, Message msg) {
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         if (target.asBinder() instanceof Binder) {
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             mCaller.sendMessage(msg);
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         } else {
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             handleMessage(msg);
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             msg.recycle();
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         }
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
602ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
603b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    void unbindCurrentClientLocked() {
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurClient != null) {
6058a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (DEBUG) Slog.v(TAG, "unbindCurrentInputLocked: client = "
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + mCurClient.client.asBinder());
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mBoundToMethod) {
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mBoundToMethod = false;
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mCurMethod != null) {
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    executeOrSendMessage(mCurMethod, mCaller.obtainMessageO(
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            MSG_UNBIND_INPUT, mCurMethod));
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    MSG_UNBIND_METHOD, mCurSeq, mCurClient.client));
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurClient.sessionRequested = false;
617ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // Call setActive(false) on the old client
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mCurClient.client.setActive(false);
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException e) {
6228a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.w(TAG, "Got RemoteException sending setActive(false) notification to pid "
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + mCurClient.pid + " uid " + mCurClient.uid);
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurClient = null;
626ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
627105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            hideInputMethodMenuLocked();
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
630ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int getImeShowFlags() {
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int flags = 0;
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mShowForced) {
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            flags |= InputMethod.SHOW_FORCED
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    | InputMethod.SHOW_EXPLICIT;
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (mShowExplicitlyRequested) {
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            flags |= InputMethod.SHOW_EXPLICIT;
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return flags;
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
641ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private int getAppShowFlags() {
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int flags = 0;
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mShowForced) {
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            flags |= InputMethodManager.SHOW_FORCED;
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (!mShowExplicitlyRequested) {
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            flags |= InputMethodManager.SHOW_IMPLICIT;
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return flags;
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
651ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    InputBindResult attachNewInputLocked(boolean initial, boolean needResult) {
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (!mBoundToMethod) {
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    MSG_BIND_INPUT, mCurMethod, mCurClient.binding));
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mBoundToMethod = true;
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final SessionState session = mCurClient.curSession;
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (initial) {
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            executeOrSendMessage(session.method, mCaller.obtainMessageOOO(
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    MSG_START_INPUT, session, mCurInputContext, mCurAttribute));
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            executeOrSendMessage(session.method, mCaller.obtainMessageOOO(
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    MSG_RESTART_INPUT, session, mCurInputContext, mCurAttribute));
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mShowRequested) {
6678a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (DEBUG) Slog.v(TAG, "Attach new input asks to show input");
6684df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            showCurrentInputLocked(getAppShowFlags(), null);
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return needResult
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ? new InputBindResult(session.session, mCurId, mCurSeq)
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                : null;
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
674ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    InputBindResult startInputLocked(IInputMethodClient client,
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            IInputContext inputContext, EditorInfo attribute,
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean initial, boolean needResult) {
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // If no method is currently selected, do nothing.
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurMethodId == null) {
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return mNoBinding;
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
682ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ClientState cs = mClients.get(client.asBinder());
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (cs == null) {
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("unknown client "
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + client.asBinder());
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
688ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!mIWindowManager.inputMethodClientHasFocus(cs.client)) {
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Check with the window manager to make sure this client actually
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // has a window with focus.  If not, reject.  This is thread safe
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // because if the focus changes some time before or after, the
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // next client receiving focus that has any interest in input will
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // be calling through here after that change happens.
6968a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.w(TAG, "Starting input on non-focused client " + cs.client
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " (uid=" + cs.uid + " pid=" + cs.pid + ")");
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return null;
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
702ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurClient != cs) {
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If the client is changing, we need to switch over to the new
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // one.
706b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project            unbindCurrentClientLocked();
7078a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (DEBUG) Slog.v(TAG, "switching to client: client = "
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + cs.client.asBinder());
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // If the screen is on, inform the new client it is active
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mScreenOn) {
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    cs.client.setActive(mScreenOn);
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (RemoteException e) {
7158a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.w(TAG, "Got RemoteException sending setActive notification to pid "
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + cs.pid + " uid " + cs.uid);
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
720ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Bump up the sequence for this client and attach it.
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCurSeq++;
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurSeq <= 0) mCurSeq = 1;
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCurClient = cs;
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCurInputContext = inputContext;
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCurAttribute = attribute;
727ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Check if the input method is changing.
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurId != null && mCurId.equals(mCurMethodId)) {
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (cs.curSession != null) {
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // Fast case: if we are already connected to the input method,
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // then just return it.
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return attachNewInputLocked(initial, needResult);
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mHaveConnection) {
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mCurMethod != null) {
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (!cs.sessionRequested) {
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        cs.sessionRequested = true;
7398a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                        if (DEBUG) Slog.v(TAG, "Creating new session for client " + cs);
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                MSG_CREATE_SESSION, mCurMethod,
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                new MethodCallback(mCurMethod)));
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // Return to client, and we will get back with it when
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // we have had a session made for it.
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return new InputBindResult(null, mCurId, mCurSeq);
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (SystemClock.uptimeMillis()
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        < (mLastBindTime+TIME_TO_RECONNECT)) {
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // In this case we have connected to the service, but
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // don't yet have its interface.  If it hasn't been too
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // long since we did the connection, we'll return to
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // the client and wait to get the service interface so
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // we can report back.  If it has been too long, we want
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // to fall through so we can try a disconnect/reconnect
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // to see if we can get back in touch with the service.
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return new InputBindResult(null, mCurId, mCurSeq);
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
758ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker                    EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME,
759ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker                            mCurMethodId, SystemClock.uptimeMillis()-mLastBindTime, 0);
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
763ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
764a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn        return startInputInnerLocked();
765a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn    }
766ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
767a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn    InputBindResult startInputInnerLocked() {
768a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn        if (mCurMethodId == null) {
769a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn            return mNoBinding;
770a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn        }
771ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
772a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn        if (!mSystemReady) {
773a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn            // If the system is not yet ready, we shouldn't be running third
774a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn            // party code.
775cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn            return new InputBindResult(null, mCurMethodId, mCurSeq);
776a34f1ad7c3a68d971e6332aa2fb1c16d083920b3Dianne Hackborn        }
777ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputMethodInfo info = mMethodMap.get(mCurMethodId);
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info == null) {
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("Unknown id: " + mCurMethodId);
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
782ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
783b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project        unbindCurrentMethodLocked(false);
784ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCurIntent = new Intent(InputMethod.SERVICE_INTERFACE);
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCurIntent.setComponent(info.getComponent());
787dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn        mCurIntent.putExtra(Intent.EXTRA_CLIENT_LABEL,
788dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn                com.android.internal.R.string.input_method_binding_label);
789dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn        mCurIntent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity(
790dd9b82c283815747b75fe4434c65e4b6c9c9b54fDianne Hackborn                mContext, 0, new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS), 0));
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mContext.bindService(mCurIntent, this, Context.BIND_AUTO_CREATE)) {
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mLastBindTime = SystemClock.uptimeMillis();
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHaveConnection = true;
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurId = info.getId();
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurToken = new Binder();
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
7978a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                if (DEBUG) Slog.v(TAG, "Adding window token: " + mCurToken);
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mIWindowManager.addWindowToken(mCurToken,
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        WindowManager.LayoutParams.TYPE_INPUT_METHOD);
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException e) {
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return new InputBindResult(null, mCurId, mCurSeq);
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurIntent = null;
8058a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.w(TAG, "Failure connecting to input method service: "
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + mCurIntent);
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
810ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public InputBindResult startInput(IInputMethodClient client,
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            IInputContext inputContext, EditorInfo attribute,
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean initial, boolean needResult) {
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mMethodMap) {
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            final long ident = Binder.clearCallingIdentity();
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return startInputLocked(client, inputContext, attribute,
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        initial, needResult);
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } finally {
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Binder.restoreCallingIdentity(ident);
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
824ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void finishInput(IInputMethodClient client) {
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
827ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onServiceConnected(ComponentName name, IBinder service) {
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mMethodMap) {
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCurIntent != null && name.equals(mCurIntent.getComponent())) {
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mCurMethod = IInputMethod.Stub.asInterface(service);
832cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn                if (mCurToken == null) {
8338a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.w(TAG, "Service connected without a token!");
834cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn                    unbindCurrentMethodLocked(false);
835cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn                    return;
836cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn                }
8378a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                if (DEBUG) Slog.v(TAG, "Initiating attach with token: " + mCurToken);
838cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn                executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
839cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn                        MSG_ATTACH_TOKEN, mCurMethod, mCurToken));
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mCurClient != null) {
8418a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    if (DEBUG) Slog.v(TAG, "Creating first session while with client "
842cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn                            + mCurClient);
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
844cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn                            MSG_CREATE_SESSION, mCurMethod,
845cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn                            new MethodCallback(mCurMethod)));
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void onSessionCreated(IInputMethod method, IInputMethodSession session) {
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mMethodMap) {
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCurMethod != null && method != null
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    && mCurMethod.asBinder() == method.asBinder()) {
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mCurClient != null) {
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCurClient.curSession = new SessionState(mCurClient,
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            method, session);
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCurClient.sessionRequested = false;
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    InputBindResult res = attachNewInputLocked(true, true);
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (res.method != null) {
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        executeOrSendMessage(mCurClient.client, mCaller.obtainMessageOO(
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                MSG_BIND_METHOD, mCurClient.client, res));
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
868ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
869b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    void unbindCurrentMethodLocked(boolean reportToClient) {
870b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project        if (mHaveConnection) {
871b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project            mContext.unbindService(this);
872b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project            mHaveConnection = false;
873b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project        }
874ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
875b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project        if (mCurToken != null) {
876b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project            try {
8778a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                if (DEBUG) Slog.v(TAG, "Removing window token: " + mCurToken);
878b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project                mIWindowManager.removeWindowToken(mCurToken);
879b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project            } catch (RemoteException e) {
880b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project            }
881b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project            mCurToken = null;
882b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project        }
883ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
884105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        mCurId = null;
885b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project        clearCurMethodLocked();
886ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
887b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project        if (reportToClient && mCurClient != null) {
888b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project            executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
889b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project                    MSG_UNBIND_METHOD, mCurSeq, mCurClient.client));
890b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project        }
891b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    }
892ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
893b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    void clearCurMethodLocked() {
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurMethod != null) {
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (ClientState cs : mClients.values()) {
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cs.sessionRequested = false;
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                cs.curSession = null;
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurMethod = null;
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mStatusBar.setIconVisibility(mInputMethodIcon, false);
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
903ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void onServiceDisconnected(ComponentName name) {
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mMethodMap) {
9068a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (DEBUG) Slog.v(TAG, "Service disconnected: " + name
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " mCurIntent=" + mCurIntent);
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCurMethod != null && mCurIntent != null
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    && name.equals(mCurIntent.getComponent())) {
910b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project                clearCurMethodLocked();
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // We consider this to be a new bind attempt, since the system
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                // should now try to restart the service for us.
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mLastBindTime = SystemClock.uptimeMillis();
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mShowRequested = mInputShown;
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mInputShown = false;
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mCurClient != null) {
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO(
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            MSG_UNBIND_METHOD, mCurSeq, mCurClient.client));
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void updateStatusIcon(IBinder token, String packageName, int iconId) {
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long ident = Binder.clearCallingIdentity();
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (token == null || mCurToken != token) {
9288a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.w(TAG, "Ignoring setInputMethod of token: " + token);
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
931ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (mMethodMap) {
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (iconId == 0) {
9348a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    if (DEBUG) Slog.d(TAG, "hide the small icon for the input method");
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mStatusBar.setIconVisibility(mInputMethodIcon, false);
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if (packageName != null) {
9378a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    if (DEBUG) Slog.d(TAG, "show a small icon for the input method");
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mInputMethodData.iconId = iconId;
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mInputMethodData.iconPackage = packageName;
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mStatusBar.updateIcon(mInputMethodIcon, mInputMethodData, null);
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mStatusBar.setIconVisibility(mInputMethodIcon, true);
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Binder.restoreCallingIdentity(ident);
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void updateFromSettingsLocked() {
950b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project        // We are assuming that whoever is changing DEFAULT_INPUT_METHOD and
951b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project        // ENABLED_INPUT_METHODS is taking care of keeping them correctly in
952b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project        // sync, so we will never have a DEFAULT_INPUT_METHOD that is not
953b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project        // enabled.
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String id = Settings.Secure.getString(mContext.getContentResolver(),
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Settings.Secure.DEFAULT_INPUT_METHOD);
956b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project        if (id != null && id.length() > 0) {
9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setInputMethodLocked(id);
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (IllegalArgumentException e) {
9608a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.w(TAG, "Unknown input method from prefs: " + id, e);
961105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project                mCurMethodId = null;
962b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project                unbindCurrentMethodLocked(true);
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
964b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project        } else {
965b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project            // There is no longer an input method set, so stop any current one.
966105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mCurMethodId = null;
967b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project            unbindCurrentMethodLocked(true);
9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
970ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void setInputMethodLocked(String id) {
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputMethodInfo info = mMethodMap.get(id);
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (info == null) {
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throw new IllegalArgumentException("Unknown id: " + mCurMethodId);
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
976ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (id.equals(mCurMethodId)) {
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
980ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final long ident = Binder.clearCallingIdentity();
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCurMethodId = id;
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Settings.Secure.putString(mContext.getContentResolver(),
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Settings.Secure.DEFAULT_INPUT_METHOD, id);
9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (ActivityManagerNative.isSystemReady()) {
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Intent intent = new Intent(Intent.ACTION_INPUT_METHOD_CHANGED);
9891c633fc89bae9bf0af6fe643ac7ad2e744f27bedDianne Hackborn                intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                intent.putExtra("input_method_id", id);
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mContext.sendBroadcast(intent);
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
993b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project            unbindCurrentClientLocked();
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Binder.restoreCallingIdentity(ident);
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
998ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
9994df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    public boolean showSoftInput(IInputMethodClient client, int flags,
10004df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            ResultReceiver resultReceiver) {
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long ident = Binder.clearCallingIdentity();
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (mMethodMap) {
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mCurClient == null || client == null
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        || mCurClient.client.asBinder() != client.asBinder()) {
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    try {
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // We need to check if this is the current client with
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // focus in the window manager, to allow this call to
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // be made before input is started in it.
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (!mIWindowManager.inputMethodClientHasFocus(client)) {
10118a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                            Slog.w(TAG, "Ignoring showSoftInput of: " + client);
10124df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                            return false;
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } catch (RemoteException e) {
10154df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                        return false;
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1018ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
10198a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                if (DEBUG) Slog.v(TAG, "Client requesting input be shown");
10204df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                return showCurrentInputLocked(flags, resultReceiver);
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Binder.restoreCallingIdentity(ident);
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1026ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
10274df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    boolean showCurrentInputLocked(int flags, ResultReceiver resultReceiver) {
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mShowRequested = true;
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((flags&InputMethodManager.SHOW_IMPLICIT) == 0) {
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mShowExplicitlyRequested = true;
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((flags&InputMethodManager.SHOW_FORCED) != 0) {
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mShowExplicitlyRequested = true;
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mShowForced = true;
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1036ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1037cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn        if (!mSystemReady) {
1038cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn            return false;
1039cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn        }
1040ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
10414df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        boolean res = false;
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mCurMethod != null) {
10434df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            executeOrSendMessage(mCurMethod, mCaller.obtainMessageIOO(
10444df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                    MSG_SHOW_SOFT_INPUT, getImeShowFlags(), mCurMethod,
10454df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                    resultReceiver));
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mInputShown = true;
10474df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            res = true;
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (mHaveConnection && SystemClock.uptimeMillis()
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                < (mLastBindTime+TIME_TO_RECONNECT)) {
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // The client has asked to have the input method shown, but
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // we have been sitting here too long with a connection to the
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // service and no interface received, so let's disconnect/connect
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // to try to prod things along.
1054ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker            EventLog.writeEvent(EventLogTags.IMF_FORCE_RECONNECT_IME, mCurMethodId,
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SystemClock.uptimeMillis()-mLastBindTime,1);
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mContext.unbindService(this);
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mContext.bindService(mCurIntent, this, Context.BIND_AUTO_CREATE);
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1059ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
10604df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        return res;
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1062ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
10634df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    public boolean hideSoftInput(IInputMethodClient client, int flags,
10644df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            ResultReceiver resultReceiver) {
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long ident = Binder.clearCallingIdentity();
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (mMethodMap) {
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mCurClient == null || client == null
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        || mCurClient.client.asBinder() != client.asBinder()) {
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    try {
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // We need to check if this is the current client with
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // focus in the window manager, to allow this call to
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // be made before input is started in it.
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (!mIWindowManager.inputMethodClientHasFocus(client)) {
10758a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                            Slog.w(TAG, "Ignoring hideSoftInput of: " + client);
10764df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                            return false;
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } catch (RemoteException e) {
10794df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                        return false;
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1082ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
10838a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                if (DEBUG) Slog.v(TAG, "Client requesting input be hidden");
10844df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                return hideCurrentInputLocked(flags, resultReceiver);
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Binder.restoreCallingIdentity(ident);
10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1090ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
10914df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    boolean hideCurrentInputLocked(int flags, ResultReceiver resultReceiver) {
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ((flags&InputMethodManager.HIDE_IMPLICIT_ONLY) != 0
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                && (mShowExplicitlyRequested || mShowForced)) {
10948a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (DEBUG) Slog.v(TAG,
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "Not hiding: explicit show not cancelled by non-explicit hide");
10964df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            return false;
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mShowForced && (flags&InputMethodManager.HIDE_NOT_ALWAYS) != 0) {
10998a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (DEBUG) Slog.v(TAG,
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    "Not hiding: forced show not cancelled by not-always hide");
11014df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            return false;
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11034df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        boolean res;
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mInputShown && mCurMethod != null) {
11054df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            executeOrSendMessage(mCurMethod, mCaller.obtainMessageOO(
11064df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                    MSG_HIDE_SOFT_INPUT, mCurMethod, resultReceiver));
11074df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            res = true;
11084df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        } else {
11094df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            res = false;
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mInputShown = false;
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mShowRequested = false;
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mShowExplicitlyRequested = false;
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mShowForced = false;
11154df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        return res;
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1117ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1118b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project    public void windowGainedFocus(IInputMethodClient client, IBinder windowToken,
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean viewHasFocus, boolean isTextEditor, int softInputMode,
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            boolean first, int windowFlags) {
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        long ident = Binder.clearCallingIdentity();
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            synchronized (mMethodMap) {
11248a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                if (DEBUG) Slog.v(TAG, "windowGainedFocus: " + client.asBinder()
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " viewHasFocus=" + viewHasFocus
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " isTextEditor=" + isTextEditor
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " softInputMode=#" + Integer.toHexString(softInputMode)
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + " first=" + first + " flags=#"
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + Integer.toHexString(windowFlags));
1130ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mCurClient == null || client == null
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        || mCurClient.client.asBinder() != client.asBinder()) {
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    try {
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // We need to check if this is the current client with
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // focus in the window manager, to allow this call to
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // be made before input is started in it.
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (!mIWindowManager.inputMethodClientHasFocus(client)) {
11388a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                            Slog.w(TAG, "Client not active, ignoring focus gain of: " + client);
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return;
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } catch (RemoteException e) {
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1144ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1145b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project                if (mCurFocusedWindow == windowToken) {
11468a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.w(TAG, "Window already focused, ignoring focus gain of: " + client);
1147b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project                    return;
1148b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project                }
1149b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project                mCurFocusedWindow = windowToken;
1150ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                switch (softInputMode&WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE) {
11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED:
11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (!isTextEditor || (softInputMode &
11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                != WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE) {
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (WindowManager.LayoutParams.mayUseInputMethod(windowFlags)) {
11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                // There is no focus view, and this window will
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                // be behind any soft input window, so hide the
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                // soft input window if it is shown.
11608a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                                if (DEBUG) Slog.v(TAG, "Unspecified window will hide input");
11614df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                                hideCurrentInputLocked(InputMethodManager.HIDE_NOT_ALWAYS, null);
11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else if (isTextEditor && (softInputMode &
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST)
11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                == WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                && (softInputMode &
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                        WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // There is a focus view, and we are navigating forward
11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // into the window, so show the input window for the user.
11708a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                            if (DEBUG) Slog.v(TAG, "Unspecified window will show input");
11714df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                            showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null);
11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    case WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED:
11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Do nothing.
11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    case WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN:
11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if ((softInputMode &
11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
11808a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                            if (DEBUG) Slog.v(TAG, "Window asks to hide input going forward");
11814df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                            hideCurrentInputLocked(0, null);
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN:
11858a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                        if (DEBUG) Slog.v(TAG, "Window asks to hide input");
11864df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                        hideCurrentInputLocked(0, null);
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    case WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE:
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if ((softInputMode &
11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != 0) {
11918a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                            if (DEBUG) Slog.v(TAG, "Window asks to show input going forward");
11924df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                            showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null);
11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    case WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE:
11968a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                        if (DEBUG) Slog.v(TAG, "Window asks to always show input");
11974df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                        showCurrentInputLocked(InputMethodManager.SHOW_IMPLICIT, null);
11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        break;
11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } finally {
12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Binder.restoreCallingIdentity(ident);
12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1205ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void showInputMethodPickerFromClient(IInputMethodClient client) {
12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mMethodMap) {
12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mCurClient == null || client == null
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    || mCurClient.client.asBinder() != client.asBinder()) {
12108a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.w(TAG, "Ignoring showInputMethodDialogFromClient of: " + client);
12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mHandler.sendEmptyMessage(MSG_SHOW_IM_PICKER);
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setInputMethod(IBinder token, String id) {
12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mMethodMap) {
12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (token == null) {
12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (mContext.checkCallingOrSelfPermission(
12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        android.Manifest.permission.WRITE_SECURE_SETTINGS)
12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        != PackageManager.PERMISSION_GRANTED) {
12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    throw new SecurityException(
12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            "Using null token requires permission "
12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            + android.Manifest.permission.WRITE_SECURE_SETTINGS);
12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if (mCurToken != token) {
12288a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.w(TAG, "Ignoring setInputMethod of token: " + token);
12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long ident = Binder.clearCallingIdentity();
12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setInputMethodLocked(id);
12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } finally {
12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Binder.restoreCallingIdentity(ident);
12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void hideMySoftInput(IBinder token, int flags) {
12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mMethodMap) {
12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (token == null || mCurToken != token) {
12448a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.w(TAG, "Ignoring hideInputMethod of token: " + token);
12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long ident = Binder.clearCallingIdentity();
12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
12494df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                hideCurrentInputLocked(flags, null);
12504df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            } finally {
12514df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                Binder.restoreCallingIdentity(ident);
12524df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            }
12534df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        }
12544df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    }
1255ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
12564df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    public void showMySoftInput(IBinder token, int flags) {
12574df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        synchronized (mMethodMap) {
12584df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            if (token == null || mCurToken != token) {
12598a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.w(TAG, "Ignoring hideInputMethod of token: " + token);
12604df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                return;
12614df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            }
12624df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            long ident = Binder.clearCallingIdentity();
12634df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            try {
12644df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                showCurrentInputLocked(flags, null);
12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } finally {
12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                Binder.restoreCallingIdentity(ident);
12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void setEnabledSessionInMainThread(SessionState session) {
12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mEnabledSession != session) {
12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mEnabledSession != null) {
12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
12758a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    if (DEBUG) Slog.v(TAG, "Disabling: " + mEnabledSession);
12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mEnabledSession.method.setSessionEnabled(
12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            mEnabledSession.session, false);
12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (RemoteException e) {
12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mEnabledSession = session;
12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
12838a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                if (DEBUG) Slog.v(TAG, "Enabling: " + mEnabledSession);
12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                session.method.setSessionEnabled(
12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        session.session, true);
12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException e) {
12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1290ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean handleMessage(Message msg) {
12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        HandlerCaller.SomeArgs args;
12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (msg.what) {
12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case MSG_SHOW_IM_PICKER:
12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                showInputMethodMenu();
12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
1297ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // ---------------------------------------------------------
1299ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case MSG_UNBIND_INPUT:
13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ((IInputMethod)msg.obj).unbindInput();
13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (RemoteException e) {
13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // There is nothing interesting about the method dying.
13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case MSG_BIND_INPUT:
13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                args = (HandlerCaller.SomeArgs)msg.obj;
13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ((IInputMethod)args.arg1).bindInput((InputBinding)args.arg2);
13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (RemoteException e) {
13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case MSG_SHOW_SOFT_INPUT:
13154df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                args = (HandlerCaller.SomeArgs)msg.obj;
13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
13174df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                    ((IInputMethod)args.arg1).showSoftInput(msg.arg1,
13184df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                            (ResultReceiver)args.arg2);
13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (RemoteException e) {
13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case MSG_HIDE_SOFT_INPUT:
13234df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                args = (HandlerCaller.SomeArgs)msg.obj;
13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
13254df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                    ((IInputMethod)args.arg1).hideSoftInput(0,
13264df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                            (ResultReceiver)args.arg2);
13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (RemoteException e) {
13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case MSG_ATTACH_TOKEN:
13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                args = (HandlerCaller.SomeArgs)msg.obj;
13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
13338a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    if (DEBUG) Slog.v(TAG, "Sending attach of token: " + args.arg2);
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ((IInputMethod)args.arg1).attachToken((IBinder)args.arg2);
13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (RemoteException e) {
13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case MSG_CREATE_SESSION:
13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                args = (HandlerCaller.SomeArgs)msg.obj;
13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ((IInputMethod)args.arg1).createSession(
13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            (IInputMethodCallback)args.arg2);
13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (RemoteException e) {
13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // ---------------------------------------------------------
1347ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case MSG_START_INPUT:
13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                args = (HandlerCaller.SomeArgs)msg.obj;
13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SessionState session = (SessionState)args.arg1;
13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    setEnabledSessionInMainThread(session);
13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    session.method.startInput((IInputContext)args.arg2,
13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            (EditorInfo)args.arg3);
13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (RemoteException e) {
13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case MSG_RESTART_INPUT:
13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                args = (HandlerCaller.SomeArgs)msg.obj;
13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    SessionState session = (SessionState)args.arg1;
13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    setEnabledSessionInMainThread(session);
13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    session.method.restartInput((IInputContext)args.arg2,
13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            (EditorInfo)args.arg3);
13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (RemoteException e) {
13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
1368ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            // ---------------------------------------------------------
1370ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case MSG_UNBIND_METHOD:
13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ((IInputMethodClient)msg.obj).onUnbindMethod(msg.arg1);
13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (RemoteException e) {
13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // There is nothing interesting about the last client dying.
13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case MSG_BIND_METHOD:
13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                args = (HandlerCaller.SomeArgs)msg.obj;
13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ((IInputMethodClient)args.arg1).onBindMethod(
13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            (InputBindResult)args.arg2);
13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (RemoteException e) {
13848a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.w(TAG, "Client died receiving input method " + args.arg2);
13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13916da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger    private boolean isSystemIme(InputMethodInfo inputMethod) {
13926da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger        return (inputMethod.getServiceInfo().applicationInfo.flags
13936da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger                & ApplicationInfo.FLAG_SYSTEM) != 0;
13946da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger    }
13956da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger
139621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    private boolean chooseNewDefaultIMELocked() {
13976da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger        List<InputMethodInfo> enabled = getEnabledInputMethodListLocked();
13986da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger        if (enabled != null && enabled.size() > 0) {
139983e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn            // We'd prefer to fall back on a system IME, since that is safer.
140083e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn            int i=enabled.size();
140183e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn            while (i > 0) {
140283e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn                i--;
140383e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn                if ((enabled.get(i).getServiceInfo().applicationInfo.flags
140483e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
140583e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn                    break;
140683e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn                }
140783e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn            }
14086da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger            Settings.Secure.putString(mContext.getContentResolver(),
14096da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger                    Settings.Secure.DEFAULT_INPUT_METHOD,
141083e48f57e937a2e582707056f164aefa3c2f7e1dDianne Hackborn                    enabled.get(i).getId());
14116da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger            return true;
14126da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger        }
14136da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger
14146da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger        return false;
14156da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger    }
14166da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger
14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void buildInputMethodListLocked(ArrayList<InputMethodInfo> list,
14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            HashMap<String, InputMethodInfo> map) {
14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        list.clear();
14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        map.clear();
1421ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        PackageManager pm = mContext.getPackageManager();
1423e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani        final Configuration config = mContext.getResources().getConfiguration();
1424e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani        final boolean haveHardKeyboard = config.keyboard == Configuration.KEYBOARD_QWERTY;
1425e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani        String disabledSysImes = Settings.Secure.getString(mContext.getContentResolver(),
1426e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani                Secure.DISABLED_SYSTEM_INPUT_METHODS);
1427e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani        if (disabledSysImes == null) disabledSysImes = "";
14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        List<ResolveInfo> services = pm.queryIntentServices(
14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                new Intent(InputMethod.SERVICE_INTERFACE),
14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                PackageManager.GET_META_DATA);
1432ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (int i = 0; i < services.size(); ++i) {
14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ResolveInfo ri = services.get(i);
14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ServiceInfo si = ri.serviceInfo;
14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ComponentName compName = new ComponentName(si.packageName, si.name);
14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!android.Manifest.permission.BIND_INPUT_METHOD.equals(
14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    si.permission)) {
14398a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.w(TAG, "Skipping input method " + compName
14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + ": it does not require the permission "
14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + android.Manifest.permission.BIND_INPUT_METHOD);
14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14458a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            if (DEBUG) Slog.d(TAG, "Checking " + compName);
14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                InputMethodInfo p = new InputMethodInfo(mContext, ri);
14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                list.add(p);
1450e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani                final String id = p.getId();
1451e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani                map.put(id, p);
14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1453e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani                // System IMEs are enabled by default, unless there's a hard keyboard
1454e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani                // and the system IME was explicitly disabled
1455e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani                if (isSystemIme(p) && (!haveHardKeyboard || disabledSysImes.indexOf(id) < 0)) {
1456e861ec11c458b4f76eb80da518dfee6a400071bfAmith Yamasani                    setInputMethodEnabledLocked(id, true);
14576da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger                }
14586da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger
14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (DEBUG) {
14608a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                    Slog.d(TAG, "Found a third-party input method " + p);
14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1462ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (XmlPullParserException e) {
14648a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.w(TAG, "Unable to load input method " + compName, e);
14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (IOException e) {
14668a9b22056b13477f59df934928c00c58b5871c95Joe Onorato                Slog.w(TAG, "Unable to load input method " + compName, e);
14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14696da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger
14706da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger        String defaultIme = Settings.Secure.getString(mContext
14716da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger                .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
14726da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger        if (!map.containsKey(defaultIme)) {
147321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            if (chooseNewDefaultIMELocked()) {
14746da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger                updateFromSettingsLocked();
14756da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger            }
14766da35a0c1205398b7df4776e359f7794584fb128Brandon Ballinger        }
14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1478ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // ----------------------------------------------------------------------
1480ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void showInputMethodMenu() {
14828a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "Show switching menu");
14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Context context = mContext;
1485ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final PackageManager pm = context.getPackageManager();
1487ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        String lastInputMethodId = Settings.Secure.getString(context
14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
14908a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "Current IME: " + lastInputMethodId);
1491ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final List<InputMethodInfo> immis = getEnabledInputMethodList();
1493ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
149497106ab5af0fdba00d6dbda4767b953e0a5829f4Dianne Hackborn        if (immis == null) {
149597106ab5af0fdba00d6dbda4767b953e0a5829f4Dianne Hackborn            return;
149697106ab5af0fdba00d6dbda4767b953e0a5829f4Dianne Hackborn        }
149797106ab5af0fdba00d6dbda4767b953e0a5829f4Dianne Hackborn
14988cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn        synchronized (mMethodMap) {
14998cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn            hideInputMethodMenuLocked();
15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15018cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn            int N = immis.size();
15028cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn
15038cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn            mItems = new CharSequence[N];
15048cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn            mIms = new InputMethodInfo[N];
15058cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn
15068cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn            int j = 0;
15078cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn            for (int i = 0; i < N; ++i) {
15088cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                InputMethodInfo property = immis.get(i);
15098cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                if (property == null) {
15108cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                    continue;
15118cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                }
15128cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                mItems[j] = property.loadLabel(pm);
15138cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                mIms[j] = property;
15148cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                j++;
15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15168cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn
15178cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn            int checkedItem = 0;
15188cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn            for (int i = 0; i < N; ++i) {
15198cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                if (mIms[i].getId().equals(lastInputMethodId)) {
15208cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                    checkedItem = i;
15218cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                    break;
15228cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                }
15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15248cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn
15258cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn            AlertDialog.OnClickListener adocl = new AlertDialog.OnClickListener() {
15268cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                public void onClick(DialogInterface dialog, int which) {
15278cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                    hideInputMethodMenu();
15288cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                }
15298cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn            };
15308cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn
15318cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn            TypedArray a = context.obtainStyledAttributes(null,
15328cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                    com.android.internal.R.styleable.DialogPreference,
15338cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                    com.android.internal.R.attr.alertDialogStyle, 0);
15348cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn            mDialogBuilder = new AlertDialog.Builder(context)
15358cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                    .setTitle(com.android.internal.R.string.select_input_method)
15368cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                    .setOnCancelListener(new OnCancelListener() {
15378cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                        public void onCancel(DialogInterface dialog) {
15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            hideInputMethodMenu();
15398cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                        }
15408cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                    })
15418cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                    .setIcon(a.getDrawable(
15428cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                            com.android.internal.R.styleable.DialogPreference_dialogTitle));
15438cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn            a.recycle();
15448cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn
15458cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn            mDialogBuilder.setSingleChoiceItems(mItems, checkedItem,
15468cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                    new AlertDialog.OnClickListener() {
15478cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                        public void onClick(DialogInterface dialog, int which) {
15488cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                            synchronized (mMethodMap) {
15498cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                                if (mIms == null || mIms.length <= which) {
15508cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                                    return;
15518cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                                }
15528cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                                InputMethodInfo im = mIms[which];
15538cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                                hideInputMethodMenu();
15548cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                                if (im != null) {
15558cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                                    setInputMethodLocked(im.getId());
15568cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                                }
155720cb56e26e91df91bd64d4251222e0d421cdbe47Dianne Hackborn                            }
15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
15598cf1bcd1d26ddbb471e4968b70e32ecabe4f7a20Dianne Hackborn                    });
15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mSwitchingDialog = mDialogBuilder.create();
15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mSwitchingDialog.getWindow().setType(
15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG);
15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mSwitchingDialog.show();
15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1567ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void hideInputMethodMenu() {
1569105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        synchronized (mMethodMap) {
1570105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            hideInputMethodMenuLocked();
1571105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        }
1572105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    }
1573ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1574105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project    void hideInputMethodMenuLocked() {
15758a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "Hide switching menu");
15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1577105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        if (mSwitchingDialog != null) {
1578105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mSwitchingDialog.dismiss();
1579105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            mSwitchingDialog = null;
15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1581ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
1582105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        mDialogBuilder = null;
1583105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        mItems = null;
1584105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project        mIms = null;
15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1586ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // ----------------------------------------------------------------------
1588ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean setInputMethodEnabled(String id, boolean enabled) {
15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mMethodMap) {
15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mContext.checkCallingOrSelfPermission(
15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    android.Manifest.permission.WRITE_SECURE_SETTINGS)
15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    != PackageManager.PERMISSION_GRANTED) {
15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                throw new SecurityException(
15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        "Requires permission "
15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        + android.Manifest.permission.WRITE_SECURE_SETTINGS);
15979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
159821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            long ident = Binder.clearCallingIdentity();
16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
160121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                return setInputMethodEnabledLocked(id, enabled);
160221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            } finally {
160321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                Binder.restoreCallingIdentity(ident);
160421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
160521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
160621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    }
160721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
160821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn    boolean setInputMethodEnabledLocked(String id, boolean enabled) {
160921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        // Make sure this is a valid input method.
161021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        InputMethodInfo imm = mMethodMap.get(id);
161121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        if (imm == null) {
161221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            if (imm == null) {
161321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                throw new IllegalArgumentException("Unknown id: " + mCurMethodId);
161421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
161521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
1616ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
161721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        StringBuilder builder = new StringBuilder(256);
1618ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
161921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        boolean removed = false;
162021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        String firstId = null;
1621ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
162221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        // Look through the currently enabled input methods.
162321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        String enabledStr = Settings.Secure.getString(mContext.getContentResolver(),
162421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                Settings.Secure.ENABLED_INPUT_METHODS);
162521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        if (enabledStr != null) {
162621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
162721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            splitter.setString(enabledStr);
162821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            while (splitter.hasNext()) {
162921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                String curId = splitter.next();
163021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                if (curId.equals(id)) {
163121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    if (enabled) {
163221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        // We are enabling this input method, but it is
163321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        // already enabled.  Nothing to do.  The previous
163421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        // state was enabled.
163521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        return true;
163621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    }
163721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    // We are disabling this input method, and it is
163821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    // currently enabled.  Skip it to remove from the
163921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    // new list.
164021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    removed = true;
164121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                } else if (!enabled) {
164221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    // We are building a new list of input methods that
164321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    // doesn't contain the given one.
164421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    if (firstId == null) firstId = curId;
164521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    if (builder.length() > 0) builder.append(':');
164621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    builder.append(curId);
16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
164821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
164921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
1650ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
165121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        if (!enabled) {
165221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            if (!removed) {
165321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                // We are disabling the input method but it is already
165421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                // disabled.  Nothing to do.  The previous state was
165521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                // disabled.
16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return false;
16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
165821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            // Update the setting with the new list of input methods.
165921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            Settings.Secure.putString(mContext.getContentResolver(),
166021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    Settings.Secure.ENABLED_INPUT_METHODS, builder.toString());
166121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            // We the disabled input method is currently selected, switch
166221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            // to another one.
166321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            String selId = Settings.Secure.getString(mContext.getContentResolver(),
166421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                    Settings.Secure.DEFAULT_INPUT_METHOD);
166521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            if (id.equals(selId)) {
166621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                Settings.Secure.putString(mContext.getContentResolver(),
166721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        Settings.Secure.DEFAULT_INPUT_METHOD,
166821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                        firstId != null ? firstId : "");
166921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            }
167021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            // Previous state was enabled.
167121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            return true;
167221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        }
167321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
167421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        // Add in the newly enabled input method.
167521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        if (enabledStr == null || enabledStr.length() == 0) {
167621f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            enabledStr = id;
167721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        } else {
167821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn            enabledStr = enabledStr + ':' + id;
16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
168021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
168121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        Settings.Secure.putString(mContext.getContentResolver(),
168221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn                Settings.Secure.ENABLED_INPUT_METHODS, enabledStr);
168321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn
168421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        // Previous state was disabled.
168521f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn        return false;
16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16874df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project
16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // ----------------------------------------------------------------------
1689ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override
16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                != PackageManager.PERMISSION_GRANTED) {
1694ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.println("Permission Denial: can't dump InputMethodManager from from pid="
16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + Binder.getCallingPid()
16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ", uid=" + Binder.getCallingUid());
16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IInputMethod method;
17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ClientState client;
1703ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Printer p = new PrintWriterPrinter(pw);
1705ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        synchronized (mMethodMap) {
17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("Current Input Method Manager state:");
17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int N = mMethodList.size();
17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  Input Methods:");
17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (int i=0; i<N; i++) {
17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                InputMethodInfo info = mMethodList.get(i);
17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                p.println("  InputMethod #" + i + ":");
17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                info.dump(p, "    ");
17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  Clients:");
17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (ClientState ci : mClients.values()) {
17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                p.println("  Client " + ci + ":");
17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                p.println("    client=" + ci.client);
17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                p.println("    inputContext=" + ci.inputContext);
17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                p.println("    sessionRequested=" + ci.sessionRequested);
17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                p.println("    curSession=" + ci.curSession);
17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
17239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  mInputMethodIcon=" + mInputMethodIcon);
17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  mInputMethodData=" + mInputMethodData);
1725105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project            p.println("  mCurMethodId=" + mCurMethodId);
17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            client = mCurClient;
1727b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project            p.println("  mCurClient=" + client + " mCurSeq=" + mCurSeq);
1728b2a3dd88a53cc8c6d19f6dc8ec4f3d6c4abd9b54The Android Open Source Project            p.println("  mCurFocusedWindow=" + mCurFocusedWindow);
17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  mCurId=" + mCurId + " mHaveConnect=" + mHaveConnection
17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " mBoundToMethod=" + mBoundToMethod);
17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  mCurToken=" + mCurToken);
17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  mCurIntent=" + mCurIntent);
17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            method = mCurMethod;
17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  mCurMethod=" + mCurMethod);
17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  mEnabledSession=" + mEnabledSession);
17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println("  mShowRequested=" + mShowRequested
17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " mShowExplicitlyRequested=" + mShowExplicitlyRequested
17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " mShowForced=" + mShowForced
17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + " mInputShown=" + mInputShown);
1740cc27870098a5b6105d6007a18bebaec8940db2d5Dianne Hackborn            p.println("  mSystemReady=" + mSystemReady + " mScreenOn=" + mScreenOn);
17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1742ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
17439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (client != null) {
17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println(" ");
17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.flush();
17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
17479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                client.client.asBinder().dump(fd, args);
17489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException e) {
17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                p.println("Input method client dead: " + e);
17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1752ab5c49c7e7f5f61040650109a76f38a443fb852dDoug Zongker
17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (method != null) {
17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            p.println(" ");
17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pw.flush();
17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                method.asBinder().dump(fd, args);
17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException e) {
17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                p.println("Input method service dead: " + e);
17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1764