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_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;
7220d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn    final Context mContext;
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    final HandlerCaller mCaller;
740c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor    final WeakReference<InputMethod> mInputMethod;
75dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn    final int mTargetSdkVersion;
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static class Notifier {
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boolean notified;
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    // NOTE: we should have a cache of these.
82c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    static final class InputMethodSessionCallbackWrapper implements InputMethod.SessionCallback {
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final Context mContext;
84c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown        final InputChannel mChannel;
8552a53526265c801b70eaf6dab1acf5c3f628f8a6Michael Wright        final IInputSessionCallback mCb;
86c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
87c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown        InputMethodSessionCallbackWrapper(Context context, InputChannel channel,
88c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                IInputSessionCallback cb) {
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mContext = context;
90c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown            mChannel = channel;
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCb = cb;
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
93c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
94c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown        @Override
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void sessionCreated(InputMethodSession session) {
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            try {
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (session != null) {
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    IInputMethodSessionWrapper wrap =
99c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                            new IInputMethodSessionWrapper(mContext, session, mChannel);
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCb.sessionCreated(wrap);
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
102c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                    if (mChannel != null) {
103c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                        mChannel.dispose();
104c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                    }
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    mCb.sessionCreated(null);
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } catch (RemoteException e) {
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public IInputMethodWrapper(AbstractInputMethodService context,
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputMethod inputMethod) {
1140c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        mTarget = new WeakReference<AbstractInputMethodService>(context);
11520d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn        mContext = context.getApplicationContext();
11620d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn        mCaller = new HandlerCaller(mContext, null, this, true /*asyncHandler*/);
1170c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        mInputMethod = new WeakReference<InputMethod>(inputMethod);
118dea3ef7967228f0ddcc03f2455a4f1254758e584Dianne Hackborn        mTargetSdkVersion = context.getApplicationInfo().targetSdkVersion;
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public InputMethod getInternalInputMethod() {
1220c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        return mInputMethod.get();
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
125c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void executeMessage(Message msg) {
1270c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        InputMethod inputMethod = mInputMethod.get();
1280c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        // Need a valid reference to the inputMethod for everything except a dump.
1290c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        if (inputMethod == null && msg.what != DO_DUMP) {
1300c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor            Log.w(TAG, "Input method reference was null, ignoring message: " + msg.what);
1310c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor            return;
1320c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        }
1330c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (msg.what) {
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_DUMP: {
1360c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                AbstractInputMethodService target = mTarget.get();
1370c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                if (target == null) {
1380c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                    return;
1390c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                }
140758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                SomeArgs args = (SomeArgs)msg.obj;
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                try {
1420c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                    target.dump((FileDescriptor)args.arg1,
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            (PrintWriter)args.arg2, (String[])args.arg3);
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } catch (RuntimeException e) {
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ((PrintWriter)args.arg2).println("Exception: " + e);
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                synchronized (args.arg4) {
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ((CountDownLatch)args.arg4).countDown();
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
150758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                args.recycle();
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_ATTACH_TOKEN: {
1550c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.attachToken((IBinder)msg.obj);
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_SET_INPUT_CONTEXT: {
1590c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.bindInput((InputBinding)msg.obj);
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_UNSET_INPUT_CONTEXT:
1630c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.unbindInput();
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_START_INPUT: {
166f7526b58960608887b064670bb42f41aa28b8f41Yohei Yukawa                final SomeArgs args = (SomeArgs) msg.obj;
167f7526b58960608887b064670bb42f41aa28b8f41Yohei Yukawa                final int missingMethods = msg.arg1;
168f7526b58960608887b064670bb42f41aa28b8f41Yohei Yukawa                final boolean restarting = msg.arg2 != 0;
1696db3bfe33d92127d203ec872a0b353585a99f256Yohei Yukawa                final IBinder startInputToken = (IBinder) args.arg1;
1706db3bfe33d92127d203ec872a0b353585a99f256Yohei Yukawa                final IInputContext inputContext = (IInputContext) args.arg2;
1716db3bfe33d92127d203ec872a0b353585a99f256Yohei Yukawa                final EditorInfo info = (EditorInfo) args.arg3;
172f7526b58960608887b064670bb42f41aa28b8f41Yohei Yukawa                final InputConnection ic = inputContext != null
1733eaf8674872824e4d44a1de7ad72529c299634f7Yohei Yukawa                        ? new InputConnectionWrapper(mTarget, inputContext, missingMethods) : null;
1743eaf8674872824e4d44a1de7ad72529c299634f7Yohei Yukawa                info.makeCompatible(mTargetSdkVersion);
1754e28668a152fb5fc1b28e0e953db27febaab485bYohei Yukawa                inputMethod.dispatchStartInputWithToken(ic, info, restarting /* restarting */,
1766db3bfe33d92127d203ec872a0b353585a99f256Yohei Yukawa                        startInputToken);
177758143ecfedbe08cc6c4fed0ad8ad7a854194ca4Svetoslav Ganov                args.recycle();
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_CREATE_SESSION: {
181c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                SomeArgs args = (SomeArgs)msg.obj;
1820c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.createSession(new InputMethodSessionCallbackWrapper(
18320d94749043d0851f1da10c7749fd7eb13a35081Dianne Hackborn                        mContext, (InputChannel)args.arg1,
184c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                        (IInputSessionCallback)args.arg2));
185c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                args.recycle();
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_SET_SESSION_ENABLED:
1890c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.setSessionEnabled((InputMethodSession)msg.obj,
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        msg.arg1 != 0);
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_REVOKE_SESSION:
1930c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.revokeSession((InputMethodSession)msg.obj);
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_SHOW_SOFT_INPUT:
1960c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.showSoftInput(msg.arg1, (ResultReceiver)msg.obj);
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DO_HIDE_SOFT_INPUT:
1990c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor                inputMethod.hideSoftInput(msg.arg1, (ResultReceiver)msg.obj);
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return;
201ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok            case DO_CHANGE_INPUTMETHOD_SUBTYPE:
202ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok                inputMethod.changeInputMethodSubtype((InputMethodSubtype)msg.obj);
203ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok                return;
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Log.w(TAG, "Unhandled message code: " + msg.what);
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
207c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
208c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
209c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
2100c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        AbstractInputMethodService target = mTarget.get();
2110c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        if (target == null) {
2120c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor            return;
2130c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        }
2140c33ed2992b2eb484c229fd3322df14d97c10caaDevin Taylor        if (target.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                != PackageManager.PERMISSION_GRANTED) {
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fout.println("Permission Denial: can't dump InputMethodManager from from pid="
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + Binder.getCallingPid()
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    + ", uid=" + Binder.getCallingUid());
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return;
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        CountDownLatch latch = new CountDownLatch(1);
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageOOOO(DO_DUMP,
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fd, fout, args, latch));
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (!latch.await(5, TimeUnit.SECONDS)) {
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                fout.println("Timeout waiting for dump");
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (InterruptedException e) {
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            fout.println("Interrupted waiting for dump");
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
235c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void attachToken(IBinder token) {
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_ATTACH_TOKEN, token));
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
239c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
240c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void bindInput(InputBinding binding) {
24219a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        // This IInputContext is guaranteed to implement all the methods.
24319a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa        final int missingMethodFlags = 0;
24445700fa135e83ed44e4b69ca60cf12960a5898d7Yohei Yukawa        InputConnection ic = new InputConnectionWrapper(mTarget,
24519a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa                IInputContext.Stub.asInterface(binding.getConnectionToken()), missingMethodFlags);
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        InputBinding nu = new InputBinding(ic, binding);
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_INPUT_CONTEXT, nu));
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
250c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void unbindInput() {
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_UNSET_INPUT_CONTEXT));
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
255c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
2566db3bfe33d92127d203ec872a0b353585a99f256Yohei Yukawa    public void startInput(IBinder startInputToken, IInputContext inputContext,
25719a80a1e807acd00bec999eaac7812da6ffce954Yohei Yukawa            @InputConnectionInspector.MissingMethodFlags final int missingMethods,
258f7526b58960608887b064670bb42f41aa28b8f41Yohei Yukawa            EditorInfo attribute, boolean restarting) {
2596db3bfe33d92127d203ec872a0b353585a99f256Yohei Yukawa        mCaller.executeOrSendMessage(mCaller.obtainMessageIIOOO(DO_START_INPUT,
2606db3bfe33d92127d203ec872a0b353585a99f256Yohei Yukawa                missingMethods, restarting ? 1 : 0, startInputToken, inputContext, attribute));
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
263c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
264c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    public void createSession(InputChannel channel, IInputSessionCallback callback) {
265c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown        mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_CREATE_SESSION,
266c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown                channel, callback));
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
269c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setSessionEnabled(IInputMethodSession session, boolean enabled) {
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputMethodSession ls = ((IInputMethodSessionWrapper)
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    session).getInternalInputMethodSession();
274240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka            if (ls == null) {
275240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka                Log.w(TAG, "Session is already finished: " + session);
276240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka                return;
277240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka            }
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCaller.executeOrSendMessage(mCaller.obtainMessageIO(
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    DO_SET_SESSION_ENABLED, enabled ? 1 : 0, ls));
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (ClassCastException e) {
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.w(TAG, "Incoming session not of correct type: " + session, e);
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
284c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
285c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void revokeSession(IInputMethodSession session) {
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            InputMethodSession ls = ((IInputMethodSessionWrapper)
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    session).getInternalInputMethodSession();
290240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka            if (ls == null) {
291240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka                Log.w(TAG, "Session is already finished: " + session);
292240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka                return;
293240b6bf97503b8747878c11ca94b8c94704e5a63Satoshi Kataoka            }
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_REVOKE_SESSION, ls));
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (ClassCastException e) {
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Log.w(TAG, "Incoming session not of correct type: " + session, e);
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
299c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
300c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
3014df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    public void showSoftInput(int flags, ResultReceiver resultReceiver) {
3024df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageIO(DO_SHOW_SOFT_INPUT,
3034df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                flags, resultReceiver));
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
305c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown
306c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
3074df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    public void hideSoftInput(int flags, ResultReceiver resultReceiver) {
3084df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        mCaller.executeOrSendMessage(mCaller.obtainMessageIO(DO_HIDE_SOFT_INPUT,
3094df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                flags, resultReceiver));
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
311ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok
312c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown    @Override
313ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    public void changeInputMethodSubtype(InputMethodSubtype subtype) {
314ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_CHANGE_INPUTMETHOD_SUBTYPE,
315ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok                subtype));
316ab751aa085433e9f735d2e7603459c6c7e9d2fb0satok    }
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
318