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