115a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root/*
215a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Copyright (C) 2008 The Android Open Source Project
315a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
415a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Licensed under the Apache License, Version 2.0 (the "License");
515a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * you may not use this file except in compliance with the License.
615a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * You may obtain a copy of the License at
715a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
815a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *      http://www.apache.org/licenses/LICENSE-2.0
915a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root *
1015a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * Unless required by applicable law or agreed to in writing, software
1115a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * distributed under the License is distributed on an "AS IS" BASIS,
1215a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1315a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * See the License for the specific language governing permissions and
1415a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root * limitations under the License.
1515a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root */
1615a4d2ffd04dc6c70f2cd17dae12ac6bc14c69abKenny Root
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.inputmethodservice;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.os.HandlerCaller;
20758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganovimport com.android.internal.os.SomeArgs;
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.IInputMethodSession;
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.view.InputConnectionWrapper;
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager;
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException;
334df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Projectimport android.os.ResultReceiver;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.EditorInfo;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputBinding;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputConnection;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethod;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethodSession;
40ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokimport android.view.inputmethod.InputMethodSubtype;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter;
440c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylorimport java.lang.ref.WeakReference;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.CountDownLatch;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.TimeUnit;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Implements the internal IInputMethod interface to convert incoming calls
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on to it back to calls on the public InputMethod interface, scheduling
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * them on the main thread of the process.
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass IInputMethodWrapper extends IInputMethod.Stub
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        implements HandlerCaller.Callback {
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "InputMethodWrapper";
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final boolean DEBUG = false;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_DUMP = 1;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_ATTACH_TOKEN = 10;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_SET_INPUT_CONTEXT = 20;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_UNSET_INPUT_CONTEXT = 30;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_START_INPUT = 32;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_RESTART_INPUT = 34;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_CREATE_SESSION = 40;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_SET_SESSION_ENABLED = 45;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_REVOKE_SESSION = 50;
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_SHOW_SOFT_INPUT = 60;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_HIDE_SOFT_INPUT = 70;
69ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    private static final int DO_CHANGE_INPUTMETHOD_SUBTYPE = 80;
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
710c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor    final WeakReference<AbstractInputMethodService> mTarget;
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final HandlerCaller mCaller;
730c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor    final WeakReference<InputMethod> mInputMethod;
74dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn    final int mTargetSdkVersion;
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static class Notifier {
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean notified;
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // NOTE: we should have a cache of these.
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static class InputMethodSessionCallbackWrapper implements InputMethod.SessionCallback {
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Context mContext;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final IInputMethodCallback mCb;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputMethodSessionCallbackWrapper(Context context, IInputMethodCallback cb) {
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mContext = context;
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCb = cb;
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void sessionCreated(InputMethodSession session) {
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (session != null) {
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    IInputMethodSessionWrapper wrap =
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            new IInputMethodSessionWrapper(mContext, session);
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCb.sessionCreated(wrap);
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCb.sessionCreated(null);
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException e) {
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public IInputMethodWrapper(AbstractInputMethodService context,
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputMethod inputMethod) {
1040c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        mTarget = new WeakReference<AbstractInputMethodService>(context);
1050c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        mCaller = new HandlerCaller(context.getApplicationContext(), this);
1060c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        mInputMethod = new WeakReference<InputMethod>(inputMethod);
107dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn        mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public InputMethod getInternalInputMethod() {
1110c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        return mInputMethod.get();
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void executeMessage(Message msg) {
1150c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        InputMethod inputMethod = mInputMethod.get();
1160c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        // Need a valid reference to the inputMethod for everything except a dump.
1170c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        if (inputMethod == null && msg.what != DO_DUMP) {
1180c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor            Log.w(TAG, "Input method reference was null, ignoring message: " + msg.what);
1190c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor            return;
1200c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        }
1210c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (msg.what) {
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_DUMP: {
1240c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                AbstractInputMethodService target = mTarget.get();
1250c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                if (target == null) {
1260c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                    return;
1270c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                }
128758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                SomeArgs args = (SomeArgs)msg.obj;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
1300c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                    target.dump((FileDescriptor)args.arg1,
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            (PrintWriter)args.arg2, (String[])args.arg3);
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (RuntimeException e) {
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ((PrintWriter)args.arg2).println("Exception: " + e);
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                synchronized (args.arg4) {
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ((CountDownLatch)args.arg4).countDown();
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
138758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                args.recycle();
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_ATTACH_TOKEN: {
1430c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.attachToken((IBinder)msg.obj);
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_SET_INPUT_CONTEXT: {
1470c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.bindInput((InputBinding)msg.obj);
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_UNSET_INPUT_CONTEXT:
1510c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.unbindInput();
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_START_INPUT: {
154758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                SomeArgs args = (SomeArgs)msg.obj;
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                IInputContext inputContext = (IInputContext)args.arg1;
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                InputConnection ic = inputContext != null
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ? new InputConnectionWrapper(inputContext) : null;
158dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn                EditorInfo info = (EditorInfo)args.arg2;
159dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn                info.makeCompatible(mTargetSdkVersion);
160dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn                inputMethod.startInput(ic, info);
161758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                args.recycle();
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_RESTART_INPUT: {
165758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                SomeArgs args = (SomeArgs)msg.obj;
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                IInputContext inputContext = (IInputContext)args.arg1;
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                InputConnection ic = inputContext != null
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ? new InputConnectionWrapper(inputContext) : null;
169dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn                EditorInfo info = (EditorInfo)args.arg2;
170dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn                info.makeCompatible(mTargetSdkVersion);
171dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn                inputMethod.restartInput(ic, info);
172758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                args.recycle();
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_CREATE_SESSION: {
1760c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.createSession(new InputMethodSessionCallbackWrapper(
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        mCaller.mContext, (IInputMethodCallback)msg.obj));
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_SET_SESSION_ENABLED:
1810c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.setSessionEnabled((InputMethodSession)msg.obj,
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        msg.arg1 != 0);
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_REVOKE_SESSION:
1850c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.revokeSession((InputMethodSession)msg.obj);
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_SHOW_SOFT_INPUT:
1880c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.showSoftInput(msg.arg1, (ResultReceiver)msg.obj);
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_HIDE_SOFT_INPUT:
1910c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.hideSoftInput(msg.arg1, (ResultReceiver)msg.obj);
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
193ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok            case DO_CHANGE_INPUTMETHOD_SUBTYPE:
194ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok                inputMethod.changeInputMethodSubtype((InputMethodSubtype)msg.obj);
195ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok                return;
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Log.w(TAG, "Unhandled message code: " + msg.what);
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    @Override protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
2010c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        AbstractInputMethodService target = mTarget.get();
2020c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        if (target == null) {
2030c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor            return;
2040c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        }
2050c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        if (target.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                != PackageManager.PERMISSION_GRANTED) {
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fout.println("Permission Denial: can't dump InputMethodManager from from pid="
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + Binder.getCallingPid()
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ", uid=" + Binder.getCallingUid());
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CountDownLatch latch = new CountDownLatch(1);
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageOOOO(DO_DUMP,
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fd, fout, args, latch));
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!latch.await(5, TimeUnit.SECONDS)) {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fout.println("Timeout waiting for dump");
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (InterruptedException e) {
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fout.println("Interrupted waiting for dump");
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void attachToken(IBinder token) {
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_ATTACH_TOKEN, token));
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void bindInput(InputBinding binding) {
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputConnection ic = new InputConnectionWrapper(
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                IInputContext.Stub.asInterface(binding.getConnectionToken()));
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputBinding nu = new InputBinding(ic, binding);
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_INPUT_CONTEXT, nu));
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void unbindInput() {
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_UNSET_INPUT_CONTEXT));
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void startInput(IInputContext inputContext, EditorInfo attribute) {
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_START_INPUT,
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                inputContext, attribute));
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void restartInput(IInputContext inputContext, EditorInfo attribute) {
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_RESTART_INPUT,
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                inputContext, attribute));
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void createSession(IInputMethodCallback callback) {
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_CREATE_SESSION, callback));
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setSessionEnabled(IInputMethodSession session, boolean enabled) {
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputMethodSession ls = ((IInputMethodSessionWrapper)
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    session).getInternalInputMethodSession();
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCaller.executeOrSendMessage(mCaller.obtainMessageIO(
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    DO_SET_SESSION_ENABLED, enabled ? 1 : 0, ls));
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (ClassCastException e) {
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.w(TAG, "Incoming session not of correct type: " + session, e);
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void revokeSession(IInputMethodSession session) {
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputMethodSession ls = ((IInputMethodSessionWrapper)
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    session).getInternalInputMethodSession();
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_REVOKE_SESSION, ls));
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (ClassCastException e) {
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.w(TAG, "Incoming session not of correct type: " + session, e);
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2764df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    public void showSoftInput(int flags, ResultReceiver resultReceiver) {
2774df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageIO(DO_SHOW_SOFT_INPUT,
2784df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                flags, resultReceiver));
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2814df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    public void hideSoftInput(int flags, ResultReceiver resultReceiver) {
2824df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageIO(DO_HIDE_SOFT_INPUT,
2834df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                flags, resultReceiver));
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
285ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok
286ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    public void changeInputMethodSubtype(InputMethodSubtype subtype) {
287ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_CHANGE_INPUTMETHOD_SUBTYPE,
288ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok                subtype));
289ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    }
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
291