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;
3919a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawaimport android.view.inputmethod.InputConnectionInspector;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethod;
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.inputmethod.InputMethodSession;
42ab751aa085433e9f735d2e7603459c6c7e9d2fb0satokimport android.view.inputmethod.InputMethodSubtype;
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileDescriptor;
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter;
460c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylorimport java.lang.ref.WeakReference;
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.CountDownLatch;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.concurrent.TimeUnit;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Implements the internal IInputMethod interface to convert incoming calls
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * on to it back to calls on the public InputMethod interface, scheduling
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * them on the main thread of the process.
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass IInputMethodWrapper extends IInputMethod.Stub
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        implements HandlerCaller.Callback {
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final String TAG = "InputMethodWrapper";
58e4bbb1cc451c7ebdad9f92968732fc4f6c21a70cCraig Mautner
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_DUMP = 1;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_ATTACH_TOKEN = 10;
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_SET_INPUT_CONTEXT = 20;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_UNSET_INPUT_CONTEXT = 30;
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_START_INPUT = 32;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_RESTART_INPUT = 34;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_CREATE_SESSION = 40;
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_SET_SESSION_ENABLED = 45;
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_REVOKE_SESSION = 50;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_SHOW_SOFT_INPUT = 60;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static final int DO_HIDE_SOFT_INPUT = 70;
70ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    private static final int DO_CHANGE_INPUTMETHOD_SUBTYPE = 80;
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
720c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor    final WeakReference<AbstractInputMethodService> mTarget;
7320d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn    final Context mContext;
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final HandlerCaller mCaller;
750c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor    final WeakReference<InputMethod> mInputMethod;
76dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn    final int mTargetSdkVersion;
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static class Notifier {
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean notified;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // NOTE: we should have a cache of these.
83c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    static final class InputMethodSessionCallbackWrapper implements InputMethod.SessionCallback {
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Context mContext;
85c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown        final InputChannel mChannel;
8652a53526265c801b70eaf6dab1acf5c3f628f8a6Michael Wright        final IInputSessionCallback mCb;
87c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
88c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown        InputMethodSessionCallbackWrapper(Context context, InputChannel channel,
89c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                IInputSessionCallback cb) {
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mContext = context;
91c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown            mChannel = channel;
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCb = cb;
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
94c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
95c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown        @Override
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void sessionCreated(InputMethodSession session) {
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (session != null) {
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    IInputMethodSessionWrapper wrap =
100c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                            new IInputMethodSessionWrapper(mContext, session, mChannel);
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCb.sessionCreated(wrap);
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
103c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                    if (mChannel != null) {
104c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                        mChannel.dispose();
105c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                    }
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCb.sessionCreated(null);
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException e) {
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public IInputMethodWrapper(AbstractInputMethodService context,
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputMethod inputMethod) {
1150c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        mTarget = new WeakReference<AbstractInputMethodService>(context);
11620d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn        mContext = context.getApplicationContext();
11720d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn        mCaller = new HandlerCaller(mContext, null, this, true /*asyncHandler*/);
1180c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        mInputMethod = new WeakReference<InputMethod>(inputMethod);
119dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn        mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public InputMethod getInternalInputMethod() {
1230c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        return mInputMethod.get();
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
126c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void executeMessage(Message msg) {
1280c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        InputMethod inputMethod = mInputMethod.get();
1290c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        // Need a valid reference to the inputMethod for everything except a dump.
1300c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        if (inputMethod == null && msg.what != DO_DUMP) {
1310c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor            Log.w(TAG, "Input method reference was null, ignoring message: " + msg.what);
1320c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor            return;
1330c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        }
1340c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (msg.what) {
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_DUMP: {
1370c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                AbstractInputMethodService target = mTarget.get();
1380c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                if (target == null) {
1390c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                    return;
1400c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                }
141758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                SomeArgs args = (SomeArgs)msg.obj;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
1430c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                    target.dump((FileDescriptor)args.arg1,
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            (PrintWriter)args.arg2, (String[])args.arg3);
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (RuntimeException e) {
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ((PrintWriter)args.arg2).println("Exception: " + e);
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                synchronized (args.arg4) {
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ((CountDownLatch)args.arg4).countDown();
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
151758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                args.recycle();
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_ATTACH_TOKEN: {
1560c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.attachToken((IBinder)msg.obj);
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_SET_INPUT_CONTEXT: {
1600c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.bindInput((InputBinding)msg.obj);
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_UNSET_INPUT_CONTEXT:
1640c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.unbindInput();
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_START_INPUT: {
167758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                SomeArgs args = (SomeArgs)msg.obj;
16819a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa                int missingMethods = msg.arg1;
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                IInputContext inputContext = (IInputContext)args.arg1;
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                InputConnection ic = inputContext != null
17119a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa                        ? new InputConnectionWrapper(inputContext, missingMethods) : null;
172dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn                EditorInfo info = (EditorInfo)args.arg2;
173dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn                info.makeCompatible(mTargetSdkVersion);
174dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn                inputMethod.startInput(ic, info);
175758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                args.recycle();
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_RESTART_INPUT: {
179758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                SomeArgs args = (SomeArgs)msg.obj;
18019a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa                int missingMethods = msg.arg1;
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                IInputContext inputContext = (IInputContext)args.arg1;
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                InputConnection ic = inputContext != null
18319a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa                        ? new InputConnectionWrapper(inputContext, missingMethods) : null;
184dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn                EditorInfo info = (EditorInfo)args.arg2;
185dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn                info.makeCompatible(mTargetSdkVersion);
186dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn                inputMethod.restartInput(ic, info);
187758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                args.recycle();
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_CREATE_SESSION: {
191c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                SomeArgs args = (SomeArgs)msg.obj;
1920c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.createSession(new InputMethodSessionCallbackWrapper(
19320d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn                        mContext, (InputChannel)args.arg1,
194c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                        (IInputSessionCallback)args.arg2));
195c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                args.recycle();
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_SET_SESSION_ENABLED:
1990c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.setSessionEnabled((InputMethodSession)msg.obj,
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        msg.arg1 != 0);
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_REVOKE_SESSION:
2030c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.revokeSession((InputMethodSession)msg.obj);
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_SHOW_SOFT_INPUT:
2060c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.showSoftInput(msg.arg1, (ResultReceiver)msg.obj);
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_HIDE_SOFT_INPUT:
2090c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.hideSoftInput(msg.arg1, (ResultReceiver)msg.obj);
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
211ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok            case DO_CHANGE_INPUTMETHOD_SUBTYPE:
212ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok                inputMethod.changeInputMethodSubtype((InputMethodSubtype)msg.obj);
213ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok                return;
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Log.w(TAG, "Unhandled message code: " + msg.what);
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
217c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
218c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
219c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
2200c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        AbstractInputMethodService target = mTarget.get();
2210c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        if (target == null) {
2220c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor            return;
2230c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        }
2240c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        if (target.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                != PackageManager.PERMISSION_GRANTED) {
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fout.println("Permission Denial: can't dump InputMethodManager from from pid="
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + Binder.getCallingPid()
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ", uid=" + Binder.getCallingUid());
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CountDownLatch latch = new CountDownLatch(1);
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageOOOO(DO_DUMP,
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fd, fout, args, latch));
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!latch.await(5, TimeUnit.SECONDS)) {
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fout.println("Timeout waiting for dump");
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (InterruptedException e) {
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fout.println("Interrupted waiting for dump");
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
245c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void attachToken(IBinder token) {
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_ATTACH_TOKEN, token));
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
249c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
250c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void bindInput(InputBinding binding) {
25219a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        // This IInputContext is guaranteed to implement all the methods.
25319a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        final int missingMethodFlags = 0;
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputConnection ic = new InputConnectionWrapper(
25519a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa                IInputContext.Stub.asInterface(binding.getConnectionToken()), missingMethodFlags);
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputBinding nu = new InputBinding(ic, binding);
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_INPUT_CONTEXT, nu));
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
260c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void unbindInput() {
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_UNSET_INPUT_CONTEXT));
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
265c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
26619a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa    public void startInput(IInputContext inputContext,
26719a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa            @InputConnectionInspector.MissingMethodFlags final int missingMethods,
26819a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa            EditorInfo attribute) {
26919a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        mCaller.executeOrSendMessage(mCaller.obtainMessageIOO(DO_START_INPUT,
27019a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa                missingMethods, inputContext, attribute));
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
273c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
27419a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa    public void restartInput(IInputContext inputContext,
27519a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa            @InputConnectionInspector.MissingMethodFlags final int missingMethods,
27619a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa            EditorInfo attribute) {
27719a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        mCaller.executeOrSendMessage(mCaller.obtainMessageIOO(DO_RESTART_INPUT,
27819a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa                missingMethods, inputContext, attribute));
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
281c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
282c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    public void createSession(InputChannel channel, IInputSessionCallback callback) {
283c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown        mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_CREATE_SESSION,
284c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                channel, callback));
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
287c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setSessionEnabled(IInputMethodSession session, boolean enabled) {
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputMethodSession ls = ((IInputMethodSessionWrapper)
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    session).getInternalInputMethodSession();
292240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka            if (ls == null) {
293240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka                Log.w(TAG, "Session is already finished: " + session);
294240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka                return;
295240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka            }
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCaller.executeOrSendMessage(mCaller.obtainMessageIO(
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    DO_SET_SESSION_ENABLED, enabled ? 1 : 0, ls));
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (ClassCastException e) {
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.w(TAG, "Incoming session not of correct type: " + session, e);
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
302c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
303c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void revokeSession(IInputMethodSession session) {
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputMethodSession ls = ((IInputMethodSessionWrapper)
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    session).getInternalInputMethodSession();
308240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka            if (ls == null) {
309240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka                Log.w(TAG, "Session is already finished: " + session);
310240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka                return;
311240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka            }
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_REVOKE_SESSION, ls));
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (ClassCastException e) {
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.w(TAG, "Incoming session not of correct type: " + session, e);
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
317c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
318c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
3194df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    public void showSoftInput(int flags, ResultReceiver resultReceiver) {
3204df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageIO(DO_SHOW_SOFT_INPUT,
3214df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                flags, resultReceiver));
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
323c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
324c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
3254df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    public void hideSoftInput(int flags, ResultReceiver resultReceiver) {
3264df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageIO(DO_HIDE_SOFT_INPUT,
3274df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                flags, resultReceiver));
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
329ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok
330c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
331ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    public void changeInputMethodSubtype(InputMethodSubtype subtype) {
332ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_CHANGE_INPUTMETHOD_SUBTYPE,
333ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok                subtype));
334ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    }
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
336