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.IInputMethodSession;
2452a53526265c801b70eaf6dab1acf5c3f628f8a6Michael Wrightimport com.android.internal.view.IInputSessionCallback;
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;
35c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownimport android.view.InputChannel;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.EditorInfo;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputBinding;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputConnection;
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethod;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethodSession;
41ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokimport android.view.inputmethod.InputMethodSubtype;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor;
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter;
450c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylorimport java.lang.ref.WeakReference;
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.CountDownLatch;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.TimeUnit;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Implements the internal IInputMethod interface to convert incoming calls
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on to it back to calls on the public InputMethod interface, scheduling
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * them on the main thread of the process.
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass IInputMethodWrapper extends IInputMethod.Stub
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        implements HandlerCaller.Callback {
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "InputMethodWrapper";
57e4bbb1cc451c7ebdad9f92968732fc4f6c21a70cCraig Mautner
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.
81c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    static final class InputMethodSessionCallbackWrapper implements InputMethod.SessionCallback {
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Context mContext;
83c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown        final InputChannel mChannel;
8452a53526265c801b70eaf6dab1acf5c3f628f8a6Michael Wright        final IInputSessionCallback mCb;
85c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
86c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown        InputMethodSessionCallbackWrapper(Context context, InputChannel channel,
87c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                IInputSessionCallback cb) {
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mContext = context;
89c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown            mChannel = channel;
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCb = cb;
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
92c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
93c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown        @Override
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void sessionCreated(InputMethodSession session) {
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (session != null) {
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    IInputMethodSessionWrapper wrap =
98c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                            new IInputMethodSessionWrapper(mContext, session, mChannel);
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCb.sessionCreated(wrap);
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
101c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                    if (mChannel != null) {
102c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                        mChannel.dispose();
103c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                    }
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCb.sessionCreated(null);
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException e) {
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public IInputMethodWrapper(AbstractInputMethodService context,
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputMethod inputMethod) {
1130c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        mTarget = new WeakReference<AbstractInputMethodService>(context);
114ed218c706d9e91e75b94c448cee2e6150aaee57fMita Yun        mCaller = new HandlerCaller(context.getApplicationContext(), null,
115ed218c706d9e91e75b94c448cee2e6150aaee57fMita Yun                this, true /*asyncHandler*/);
1160c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        mInputMethod = new WeakReference<InputMethod>(inputMethod);
117dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn        mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public InputMethod getInternalInputMethod() {
1210c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        return mInputMethod.get();
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
124c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void executeMessage(Message msg) {
1260c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        InputMethod inputMethod = mInputMethod.get();
1270c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        // Need a valid reference to the inputMethod for everything except a dump.
1280c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        if (inputMethod == null && msg.what != DO_DUMP) {
1290c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor            Log.w(TAG, "Input method reference was null, ignoring message: " + msg.what);
1300c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor            return;
1310c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        }
1320c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (msg.what) {
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_DUMP: {
1350c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                AbstractInputMethodService target = mTarget.get();
1360c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                if (target == null) {
1370c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                    return;
1380c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                }
139758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                SomeArgs args = (SomeArgs)msg.obj;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
1410c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                    target.dump((FileDescriptor)args.arg1,
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            (PrintWriter)args.arg2, (String[])args.arg3);
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (RuntimeException e) {
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ((PrintWriter)args.arg2).println("Exception: " + e);
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                synchronized (args.arg4) {
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ((CountDownLatch)args.arg4).countDown();
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
149758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                args.recycle();
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_ATTACH_TOKEN: {
1540c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.attachToken((IBinder)msg.obj);
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_SET_INPUT_CONTEXT: {
1580c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.bindInput((InputBinding)msg.obj);
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_UNSET_INPUT_CONTEXT:
1620c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.unbindInput();
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_START_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.startInput(ic, info);
172758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                args.recycle();
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_RESTART_INPUT: {
176758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                SomeArgs args = (SomeArgs)msg.obj;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                IInputContext inputContext = (IInputContext)args.arg1;
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                InputConnection ic = inputContext != null
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        ? new InputConnectionWrapper(inputContext) : null;
180dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn                EditorInfo info = (EditorInfo)args.arg2;
181dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn                info.makeCompatible(mTargetSdkVersion);
182dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn                inputMethod.restartInput(ic, info);
183758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                args.recycle();
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_CREATE_SESSION: {
187c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                SomeArgs args = (SomeArgs)msg.obj;
1880c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.createSession(new InputMethodSessionCallbackWrapper(
189c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                        mCaller.mContext, (InputChannel)args.arg1,
190c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                        (IInputSessionCallback)args.arg2));
191c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                args.recycle();
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_SET_SESSION_ENABLED:
1950c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.setSessionEnabled((InputMethodSession)msg.obj,
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        msg.arg1 != 0);
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_REVOKE_SESSION:
1990c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.revokeSession((InputMethodSession)msg.obj);
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_SHOW_SOFT_INPUT:
2020c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.showSoftInput(msg.arg1, (ResultReceiver)msg.obj);
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_HIDE_SOFT_INPUT:
2050c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.hideSoftInput(msg.arg1, (ResultReceiver)msg.obj);
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
207ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok            case DO_CHANGE_INPUTMETHOD_SUBTYPE:
208ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok                inputMethod.changeInputMethodSubtype((InputMethodSubtype)msg.obj);
209ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok                return;
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Log.w(TAG, "Unhandled message code: " + msg.what);
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
213c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
214c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
215c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
2160c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        AbstractInputMethodService target = mTarget.get();
2170c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        if (target == null) {
2180c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor            return;
2190c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        }
2200c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        if (target.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                != PackageManager.PERMISSION_GRANTED) {
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fout.println("Permission Denial: can't dump InputMethodManager from from pid="
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + Binder.getCallingPid()
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ", uid=" + Binder.getCallingUid());
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CountDownLatch latch = new CountDownLatch(1);
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageOOOO(DO_DUMP,
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fd, fout, args, latch));
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!latch.await(5, TimeUnit.SECONDS)) {
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fout.println("Timeout waiting for dump");
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (InterruptedException e) {
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fout.println("Interrupted waiting for dump");
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
241c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void attachToken(IBinder token) {
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_ATTACH_TOKEN, token));
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
245c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
246c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void bindInput(InputBinding binding) {
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputConnection ic = new InputConnectionWrapper(
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                IInputContext.Stub.asInterface(binding.getConnectionToken()));
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputBinding nu = new InputBinding(ic, binding);
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_INPUT_CONTEXT, nu));
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
254c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void unbindInput() {
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_UNSET_INPUT_CONTEXT));
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
259c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void startInput(IInputContext inputContext, EditorInfo attribute) {
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_START_INPUT,
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                inputContext, attribute));
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
265c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void restartInput(IInputContext inputContext, EditorInfo attribute) {
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_RESTART_INPUT,
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                inputContext, attribute));
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
271c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
272c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    public void createSession(InputChannel channel, IInputSessionCallback callback) {
273c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown        mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_CREATE_SESSION,
274c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                channel, callback));
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
277c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setSessionEnabled(IInputMethodSession session, boolean enabled) {
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputMethodSession ls = ((IInputMethodSessionWrapper)
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    session).getInternalInputMethodSession();
282240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka            if (ls == null) {
283240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka                Log.w(TAG, "Session is already finished: " + session);
284240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka                return;
285240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka            }
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCaller.executeOrSendMessage(mCaller.obtainMessageIO(
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    DO_SET_SESSION_ENABLED, enabled ? 1 : 0, ls));
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (ClassCastException e) {
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.w(TAG, "Incoming session not of correct type: " + session, e);
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
292c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
293c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void revokeSession(IInputMethodSession session) {
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputMethodSession ls = ((IInputMethodSessionWrapper)
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    session).getInternalInputMethodSession();
298240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka            if (ls == null) {
299240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka                Log.w(TAG, "Session is already finished: " + session);
300240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka                return;
301240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka            }
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_REVOKE_SESSION, ls));
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (ClassCastException e) {
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.w(TAG, "Incoming session not of correct type: " + session, e);
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
307c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
308c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
3094df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    public void showSoftInput(int flags, ResultReceiver resultReceiver) {
3104df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageIO(DO_SHOW_SOFT_INPUT,
3114df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                flags, resultReceiver));
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
313c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
314c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
3154df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    public void hideSoftInput(int flags, ResultReceiver resultReceiver) {
3164df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageIO(DO_HIDE_SOFT_INPUT,
3174df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                flags, resultReceiver));
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
319ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok
320c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
321ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    public void changeInputMethodSubtype(InputMethodSubtype subtype) {
322ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_CHANGE_INPUTMETHOD_SUBTYPE,
323ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok                subtype));
324ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    }
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
326