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