IInputConnectionWrapper.java revision f1e484acb594a726fb57ad0ae4cfe902c7f35858
1package com.android.internal.view;
2
3import com.android.internal.view.IInputContext;
4
5import android.os.Bundle;
6import android.os.Handler;
7import android.os.Looper;
8import android.os.Message;
9import android.os.RemoteException;
10import android.util.Log;
11import android.view.KeyEvent;
12import android.view.inputmethod.CompletionInfo;
13import android.view.inputmethod.ExtractedTextRequest;
14import android.view.inputmethod.InputConnection;
15
16public class IInputConnectionWrapper extends IInputContext.Stub {
17    static final String TAG = "IInputConnectionWrapper";
18
19    private static final int DO_GET_TEXT_AFTER_CURSOR = 10;
20    private static final int DO_GET_TEXT_BEFORE_CURSOR = 20;
21    private static final int DO_GET_CURSOR_CAPS_MODE = 30;
22    private static final int DO_GET_EXTRACTED_TEXT = 40;
23    private static final int DO_COMMIT_TEXT = 50;
24    private static final int DO_COMMIT_COMPLETION = 55;
25    private static final int DO_SET_COMPOSING_TEXT = 60;
26    private static final int DO_FINISH_COMPOSING_TEXT = 65;
27    private static final int DO_SEND_KEY_EVENT = 70;
28    private static final int DO_DELETE_SURROUNDING_TEXT = 80;
29    private static final int DO_BEGIN_BATCH_EDIT = 90;
30    private static final int DO_END_BATCH_EDIT = 95;
31    private static final int DO_HIDE_STATUS_ICON = 100;
32    private static final int DO_SHOW_STATUS_ICON = 110;
33    private static final int DO_PERFORM_PRIVATE_COMMAND = 120;
34    private static final int DO_CLEAR_META_KEY_STATES = 130;
35
36    private InputConnection mInputConnection;
37
38    private Looper mMainLooper;
39    private Handler mH;
40
41    static class SomeArgs {
42        Object arg1;
43        Object arg2;
44        IInputContextCallback callback;
45        int seq;
46    }
47
48    class MyHandler extends Handler {
49        MyHandler(Looper looper) {
50            super(looper);
51        }
52
53        @Override
54        public void handleMessage(Message msg) {
55            executeMessage(msg);
56        }
57    }
58
59    public IInputConnectionWrapper(Looper mainLooper, InputConnection conn) {
60        mInputConnection = conn;
61        mMainLooper = mainLooper;
62        mH = new MyHandler(mMainLooper);
63    }
64
65    public void getTextAfterCursor(int length, int seq, IInputContextCallback callback) {
66        dispatchMessage(obtainMessageISC(DO_GET_TEXT_AFTER_CURSOR, length, seq, callback));
67    }
68
69    public void getTextBeforeCursor(int length, int seq, IInputContextCallback callback) {
70        dispatchMessage(obtainMessageISC(DO_GET_TEXT_BEFORE_CURSOR, length, seq, callback));
71    }
72
73    public void getCursorCapsMode(int reqModes, int seq, IInputContextCallback callback) {
74        dispatchMessage(obtainMessageISC(DO_GET_CURSOR_CAPS_MODE, reqModes, seq, callback));
75    }
76
77    public void getExtractedText(ExtractedTextRequest request,
78            int flags, int seq, IInputContextCallback callback) {
79        dispatchMessage(obtainMessageIOSC(DO_GET_EXTRACTED_TEXT, flags,
80                request, seq, callback));
81    }
82
83    public void commitText(CharSequence text, int newCursorPosition) {
84        dispatchMessage(obtainMessageIO(DO_COMMIT_TEXT, newCursorPosition, text));
85    }
86
87    public void commitCompletion(CompletionInfo text) {
88        dispatchMessage(obtainMessageO(DO_COMMIT_COMPLETION, text));
89    }
90
91    public void setComposingText(CharSequence text, int newCursorPosition) {
92        dispatchMessage(obtainMessageIO(DO_SET_COMPOSING_TEXT, newCursorPosition, text));
93    }
94
95    public void finishComposingText() {
96        dispatchMessage(obtainMessage(DO_FINISH_COMPOSING_TEXT));
97    }
98
99    public void sendKeyEvent(KeyEvent event) {
100        dispatchMessage(obtainMessageO(DO_SEND_KEY_EVENT, event));
101    }
102
103    public void clearMetaKeyStates(int states) {
104        dispatchMessage(obtainMessageII(DO_CLEAR_META_KEY_STATES, states, 0));
105    }
106
107    public void deleteSurroundingText(int leftLength, int rightLength) {
108        dispatchMessage(obtainMessageII(DO_DELETE_SURROUNDING_TEXT,
109            leftLength, rightLength));
110    }
111
112    public void beginBatchEdit() {
113        dispatchMessage(obtainMessage(DO_BEGIN_BATCH_EDIT));
114    }
115
116    public void endBatchEdit() {
117        dispatchMessage(obtainMessage(DO_END_BATCH_EDIT));
118    }
119
120    public void hideStatusIcon() {
121        dispatchMessage(obtainMessage(DO_HIDE_STATUS_ICON));
122    }
123
124    public void showStatusIcon(String packageName, int resId) {
125        dispatchMessage(obtainMessageIO(DO_SHOW_STATUS_ICON, resId, packageName));
126    }
127
128    public void performPrivateCommand(String action, Bundle data) {
129        dispatchMessage(obtainMessageOO(DO_PERFORM_PRIVATE_COMMAND, action, data));
130    }
131
132    void dispatchMessage(Message msg) {
133        // If we are calling this from the main thread, then we can call
134        // right through.  Otherwise, we need to send the message to the
135        // main thread.
136        if (Looper.myLooper() == mMainLooper) {
137            executeMessage(msg);
138            msg.recycle();
139            return;
140        }
141
142        mH.sendMessage(msg);
143    }
144
145    void executeMessage(Message msg) {
146        switch (msg.what) {
147            case DO_GET_TEXT_AFTER_CURSOR: {
148                SomeArgs args = (SomeArgs)msg.obj;
149                try {
150                    args.callback.setTextAfterCursor(mInputConnection.getTextAfterCursor(msg.arg1),
151                            args.seq);
152                } catch (RemoteException e) {
153                    Log.w(TAG, "Got RemoteException calling setTextAfterCursor", e);
154                }
155                return;
156            }
157            case DO_GET_TEXT_BEFORE_CURSOR: {
158                SomeArgs args = (SomeArgs)msg.obj;
159                try {
160                    args.callback.setTextBeforeCursor(mInputConnection.getTextBeforeCursor(msg.arg1),
161                            args.seq);
162                } catch (RemoteException e) {
163                    Log.w(TAG, "Got RemoteException calling setTextBeforeCursor", e);
164                }
165                return;
166            }
167            case DO_GET_CURSOR_CAPS_MODE: {
168                SomeArgs args = (SomeArgs)msg.obj;
169                try {
170                    args.callback.setCursorCapsMode(mInputConnection.getCursorCapsMode(msg.arg1),
171                            args.seq);
172                } catch (RemoteException e) {
173                    Log.w(TAG, "Got RemoteException calling setCursorCapsMode", e);
174                }
175                return;
176            }
177            case DO_GET_EXTRACTED_TEXT: {
178                SomeArgs args = (SomeArgs)msg.obj;
179                try {
180                    args.callback.setExtractedText(mInputConnection.getExtractedText(
181                            (ExtractedTextRequest)args.arg1, msg.arg1), args.seq);
182                } catch (RemoteException e) {
183                    Log.w(TAG, "Got RemoteException calling setExtractedText", e);
184                }
185                return;
186            }
187            case DO_COMMIT_TEXT: {
188                mInputConnection.commitText((CharSequence)msg.obj, msg.arg1);
189                return;
190            }
191            case DO_COMMIT_COMPLETION: {
192                mInputConnection.commitCompletion((CompletionInfo)msg.obj);
193                return;
194            }
195            case DO_SET_COMPOSING_TEXT: {
196                mInputConnection.setComposingText((CharSequence)msg.obj, msg.arg1);
197                return;
198            }
199            case DO_FINISH_COMPOSING_TEXT: {
200                mInputConnection.finishComposingText();
201                return;
202            }
203            case DO_SEND_KEY_EVENT: {
204                mInputConnection.sendKeyEvent((KeyEvent)msg.obj);
205                return;
206            }
207            case DO_CLEAR_META_KEY_STATES: {
208                mInputConnection.clearMetaKeyStates(msg.arg1);
209                return;
210            }
211            case DO_DELETE_SURROUNDING_TEXT: {
212                mInputConnection.deleteSurroundingText(msg.arg1, msg.arg2);
213                return;
214            }
215            case DO_BEGIN_BATCH_EDIT: {
216                mInputConnection.beginBatchEdit();
217                return;
218            }
219            case DO_END_BATCH_EDIT: {
220                mInputConnection.beginBatchEdit();
221                return;
222            }
223            case DO_HIDE_STATUS_ICON: {
224                mInputConnection.hideStatusIcon();
225                return;
226            }
227            case DO_SHOW_STATUS_ICON: {
228                mInputConnection.showStatusIcon((String)msg.obj, msg.arg1);
229                return;
230            }
231            case DO_PERFORM_PRIVATE_COMMAND: {
232                SomeArgs args = (SomeArgs)msg.obj;
233                mInputConnection.performPrivateCommand((String)args.arg1,
234                        (Bundle)args.arg2);
235                return;
236            }
237        }
238        Log.w(TAG, "Unhandled message code: " + msg.what);
239    }
240
241    Message obtainMessage(int what) {
242        return mH.obtainMessage(what);
243    }
244
245    Message obtainMessageII(int what, int arg1, int arg2) {
246        return mH.obtainMessage(what, arg1, arg2);
247    }
248
249    Message obtainMessageO(int what, Object arg1) {
250        return mH.obtainMessage(what, 0, 0, arg1);
251    }
252
253    Message obtainMessageISC(int what, int arg1, int seq, IInputContextCallback callback) {
254        SomeArgs args = new SomeArgs();
255        args.callback = callback;
256        args.seq = seq;
257        return mH.obtainMessage(what, arg1, 0, args);
258    }
259
260    Message obtainMessageIOSC(int what, int arg1, Object arg2, int seq,
261            IInputContextCallback callback) {
262        SomeArgs args = new SomeArgs();
263        args.arg1 = arg2;
264        args.callback = callback;
265        args.seq = seq;
266        return mH.obtainMessage(what, arg1, 0, args);
267    }
268
269    Message obtainMessageIO(int what, int arg1, Object arg2) {
270        return mH.obtainMessage(what, arg1, 0, arg2);
271    }
272
273    Message obtainMessageOO(int what, Object arg1, Object arg2) {
274        SomeArgs args = new SomeArgs();
275        args.arg1 = arg1;
276        args.arg2 = arg2;
277        return mH.obtainMessage(what, 0, 0, args);
278    }
279}
280