blob: 189c8d5913d00f3aaff953c0e2cefd6717e230ef [file] [log] [blame]
Kenny Root15a4d2f2010-03-11 18:20:12 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080017package com.android.internal.view;
18
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070019import com.android.internal.annotations.GuardedBy;
Yohei Yukawace82eb22017-02-12 23:16:47 -080020import com.android.internal.os.SomeArgs;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070021
22import android.annotation.NonNull;
23import android.annotation.Nullable;
Mathew Inwoodaf972c82018-08-20 14:13:20 +010024import android.annotation.UnsupportedAppUsage;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.os.Bundle;
26import android.os.Handler;
27import android.os.Looper;
28import android.os.Message;
29import android.os.RemoteException;
30import android.util.Log;
31import android.view.KeyEvent;
32import android.view.inputmethod.CompletionInfo;
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -080033import android.view.inputmethod.CorrectionInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.view.inputmethod.ExtractedTextRequest;
35import android.view.inputmethod.InputConnection;
Yohei Yukawa9f9afe522016-03-30 12:03:51 -070036import android.view.inputmethod.InputConnectionInspector;
37import android.view.inputmethod.InputConnectionInspector.MissingMethodFlags;
Yohei Yukawa152944f2016-06-10 19:04:34 -070038import android.view.inputmethod.InputContentInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039
Yohei Yukawa159dd472016-01-07 16:52:33 -080040public abstract class IInputConnectionWrapper extends IInputContext.Stub {
Yohei Yukawa77e51832017-02-12 20:08:13 -080041 private static final String TAG = "IInputConnectionWrapper";
42 private static final boolean DEBUG = false;
Amith Yamasania90b7f02010-08-25 18:27:20 -070043
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044 private static final int DO_GET_TEXT_AFTER_CURSOR = 10;
45 private static final int DO_GET_TEXT_BEFORE_CURSOR = 20;
Amith Yamasania90b7f02010-08-25 18:27:20 -070046 private static final int DO_GET_SELECTED_TEXT = 25;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047 private static final int DO_GET_CURSOR_CAPS_MODE = 30;
48 private static final int DO_GET_EXTRACTED_TEXT = 40;
49 private static final int DO_COMMIT_TEXT = 50;
50 private static final int DO_COMMIT_COMPLETION = 55;
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -080051 private static final int DO_COMMIT_CORRECTION = 56;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052 private static final int DO_SET_SELECTION = 57;
53 private static final int DO_PERFORM_EDITOR_ACTION = 58;
54 private static final int DO_PERFORM_CONTEXT_MENU_ACTION = 59;
55 private static final int DO_SET_COMPOSING_TEXT = 60;
Amith Yamasania90b7f02010-08-25 18:27:20 -070056 private static final int DO_SET_COMPOSING_REGION = 63;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057 private static final int DO_FINISH_COMPOSING_TEXT = 65;
58 private static final int DO_SEND_KEY_EVENT = 70;
59 private static final int DO_DELETE_SURROUNDING_TEXT = 80;
Yohei Yukawac89e22a2016-01-13 22:48:14 -080060 private static final int DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS = 81;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061 private static final int DO_BEGIN_BATCH_EDIT = 90;
62 private static final int DO_END_BATCH_EDIT = 95;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 private static final int DO_PERFORM_PRIVATE_COMMAND = 120;
64 private static final int DO_CLEAR_META_KEY_STATES = 130;
Yohei Yukawaa277db22014-08-21 18:38:44 -070065 private static final int DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO = 140;
Yohei Yukawa9f9afe522016-03-30 12:03:51 -070066 private static final int DO_CLOSE_CONNECTION = 150;
Yohei Yukawaadebb522016-06-17 10:10:39 -070067 private static final int DO_COMMIT_CONTENT = 160;
Amith Yamasania90b7f02010-08-25 18:27:20 -070068
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070069 @GuardedBy("mLock")
70 @Nullable
Mathew Inwoodaf972c82018-08-20 14:13:20 +010071 @UnsupportedAppUsage
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070072 private InputConnection mInputConnection;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073
74 private Looper mMainLooper;
75 private Handler mH;
Mathew Inwoodaf972c82018-08-20 14:13:20 +010076 @UnsupportedAppUsage
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070077 private Object mLock = new Object();
78 @GuardedBy("mLock")
79 private boolean mFinished = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081 class MyHandler extends Handler {
82 MyHandler(Looper looper) {
83 super(looper);
84 }
85
86 @Override
87 public void handleMessage(Message msg) {
88 executeMessage(msg);
89 }
90 }
91
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070092 public IInputConnectionWrapper(Looper mainLooper, @NonNull InputConnection inputConnection) {
93 mInputConnection = inputConnection;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 mMainLooper = mainLooper;
95 mH = new MyHandler(mMainLooper);
96 }
97
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070098 @Nullable
99 public InputConnection getInputConnection() {
100 synchronized (mLock) {
101 return mInputConnection;
102 }
103 }
104
105 protected boolean isFinished() {
106 synchronized (mLock) {
107 return mFinished;
108 }
109 }
110
Yohei Yukawa159dd472016-01-07 16:52:33 -0800111 abstract protected boolean isActive();
112
113 /**
114 * Called when the user took some actions that should be taken into consideration to update the
115 * LRU list for input method rotation.
116 */
117 abstract protected void onUserAction();
118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119 public void getTextAfterCursor(int length, int flags, int seq, IInputContextCallback callback) {
120 dispatchMessage(obtainMessageIISC(DO_GET_TEXT_AFTER_CURSOR, length, flags, seq, callback));
121 }
122
123 public void getTextBeforeCursor(int length, int flags, int seq, IInputContextCallback callback) {
124 dispatchMessage(obtainMessageIISC(DO_GET_TEXT_BEFORE_CURSOR, length, flags, seq, callback));
125 }
126
Amith Yamasania90b7f02010-08-25 18:27:20 -0700127 public void getSelectedText(int flags, int seq, IInputContextCallback callback) {
128 dispatchMessage(obtainMessageISC(DO_GET_SELECTED_TEXT, flags, seq, callback));
129 }
130
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131 public void getCursorCapsMode(int reqModes, int seq, IInputContextCallback callback) {
132 dispatchMessage(obtainMessageISC(DO_GET_CURSOR_CAPS_MODE, reqModes, seq, callback));
133 }
134
135 public void getExtractedText(ExtractedTextRequest request,
136 int flags, int seq, IInputContextCallback callback) {
137 dispatchMessage(obtainMessageIOSC(DO_GET_EXTRACTED_TEXT, flags,
138 request, seq, callback));
139 }
140
141 public void commitText(CharSequence text, int newCursorPosition) {
142 dispatchMessage(obtainMessageIO(DO_COMMIT_TEXT, newCursorPosition, text));
143 }
144
145 public void commitCompletion(CompletionInfo text) {
146 dispatchMessage(obtainMessageO(DO_COMMIT_COMPLETION, text));
147 }
148
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800149 public void commitCorrection(CorrectionInfo info) {
150 dispatchMessage(obtainMessageO(DO_COMMIT_CORRECTION, info));
151 }
152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 public void setSelection(int start, int end) {
154 dispatchMessage(obtainMessageII(DO_SET_SELECTION, start, end));
155 }
156
157 public void performEditorAction(int id) {
158 dispatchMessage(obtainMessageII(DO_PERFORM_EDITOR_ACTION, id, 0));
159 }
160
161 public void performContextMenuAction(int id) {
162 dispatchMessage(obtainMessageII(DO_PERFORM_CONTEXT_MENU_ACTION, id, 0));
163 }
164
Amith Yamasania90b7f02010-08-25 18:27:20 -0700165 public void setComposingRegion(int start, int end) {
166 dispatchMessage(obtainMessageII(DO_SET_COMPOSING_REGION, start, end));
167 }
168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 public void setComposingText(CharSequence text, int newCursorPosition) {
170 dispatchMessage(obtainMessageIO(DO_SET_COMPOSING_TEXT, newCursorPosition, text));
171 }
172
173 public void finishComposingText() {
174 dispatchMessage(obtainMessage(DO_FINISH_COMPOSING_TEXT));
175 }
176
177 public void sendKeyEvent(KeyEvent event) {
178 dispatchMessage(obtainMessageO(DO_SEND_KEY_EVENT, event));
179 }
180
181 public void clearMetaKeyStates(int states) {
182 dispatchMessage(obtainMessageII(DO_CLEAR_META_KEY_STATES, states, 0));
183 }
184
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800185 public void deleteSurroundingText(int beforeLength, int afterLength) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 dispatchMessage(obtainMessageII(DO_DELETE_SURROUNDING_TEXT,
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800187 beforeLength, afterLength));
188 }
189
190 public void deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
191 dispatchMessage(obtainMessageII(DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS,
192 beforeLength, afterLength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193 }
194
195 public void beginBatchEdit() {
196 dispatchMessage(obtainMessage(DO_BEGIN_BATCH_EDIT));
197 }
198
199 public void endBatchEdit() {
200 dispatchMessage(obtainMessage(DO_END_BATCH_EDIT));
201 }
202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 public void performPrivateCommand(String action, Bundle data) {
204 dispatchMessage(obtainMessageOO(DO_PERFORM_PRIVATE_COMMAND, action, data));
205 }
satokadb43582011-03-09 10:08:47 +0900206
Yohei Yukawaa277db22014-08-21 18:38:44 -0700207 public void requestUpdateCursorAnchorInfo(int cursorUpdateMode, int seq,
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900208 IInputContextCallback callback) {
Yohei Yukawaa277db22014-08-21 18:38:44 -0700209 dispatchMessage(obtainMessageISC(DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO, cursorUpdateMode,
210 seq, callback));
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900211 }
212
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700213 public void closeConnection() {
214 dispatchMessage(obtainMessage(DO_CLOSE_CONNECTION));
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700215 }
216
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700217 public void commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts,
Yohei Yukawa152944f2016-06-10 19:04:34 -0700218 int seq, IInputContextCallback callback) {
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700219 dispatchMessage(obtainMessageIOOSC(DO_COMMIT_CONTENT, flags, inputContentInfo, opts, seq,
220 callback));
Yohei Yukawa152944f2016-06-10 19:04:34 -0700221 }
222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 void dispatchMessage(Message msg) {
224 // If we are calling this from the main thread, then we can call
225 // right through. Otherwise, we need to send the message to the
226 // main thread.
227 if (Looper.myLooper() == mMainLooper) {
228 executeMessage(msg);
229 msg.recycle();
230 return;
231 }
232
233 mH.sendMessage(msg);
234 }
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700235
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236 void executeMessage(Message msg) {
237 switch (msg.what) {
238 case DO_GET_TEXT_AFTER_CURSOR: {
239 SomeArgs args = (SomeArgs)msg.obj;
240 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800241 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
242 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700243 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 if (ic == null || !isActive()) {
245 Log.w(TAG, "getTextAfterCursor on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800246 callback.setTextAfterCursor(null, callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 return;
248 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800249 callback.setTextAfterCursor(ic.getTextAfterCursor(
250 msg.arg1, msg.arg2), callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 } catch (RemoteException e) {
252 Log.w(TAG, "Got RemoteException calling setTextAfterCursor", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800253 } finally {
254 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255 }
256 return;
257 }
258 case DO_GET_TEXT_BEFORE_CURSOR: {
259 SomeArgs args = (SomeArgs)msg.obj;
260 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800261 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
262 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700263 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 if (ic == null || !isActive()) {
265 Log.w(TAG, "getTextBeforeCursor on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800266 callback.setTextBeforeCursor(null, callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 return;
268 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800269 callback.setTextBeforeCursor(ic.getTextBeforeCursor(
270 msg.arg1, msg.arg2), callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271 } catch (RemoteException e) {
272 Log.w(TAG, "Got RemoteException calling setTextBeforeCursor", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800273 } finally {
274 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 }
276 return;
277 }
Amith Yamasania90b7f02010-08-25 18:27:20 -0700278 case DO_GET_SELECTED_TEXT: {
279 SomeArgs args = (SomeArgs)msg.obj;
280 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800281 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
282 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700283 InputConnection ic = getInputConnection();
Amith Yamasania90b7f02010-08-25 18:27:20 -0700284 if (ic == null || !isActive()) {
285 Log.w(TAG, "getSelectedText on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800286 callback.setSelectedText(null, callbackSeq);
Amith Yamasania90b7f02010-08-25 18:27:20 -0700287 return;
288 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800289 callback.setSelectedText(ic.getSelectedText(
290 msg.arg1), callbackSeq);
Amith Yamasania90b7f02010-08-25 18:27:20 -0700291 } catch (RemoteException e) {
292 Log.w(TAG, "Got RemoteException calling setSelectedText", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800293 } finally {
294 args.recycle();
Amith Yamasania90b7f02010-08-25 18:27:20 -0700295 }
296 return;
297 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298 case DO_GET_CURSOR_CAPS_MODE: {
299 SomeArgs args = (SomeArgs)msg.obj;
300 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800301 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
302 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700303 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 if (ic == null || !isActive()) {
305 Log.w(TAG, "getCursorCapsMode on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800306 callback.setCursorCapsMode(0, callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 return;
308 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800309 callback.setCursorCapsMode(ic.getCursorCapsMode(msg.arg1),
310 callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 } catch (RemoteException e) {
312 Log.w(TAG, "Got RemoteException calling setCursorCapsMode", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800313 } finally {
314 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 }
316 return;
317 }
318 case DO_GET_EXTRACTED_TEXT: {
319 SomeArgs args = (SomeArgs)msg.obj;
320 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800321 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
322 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700323 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324 if (ic == null || !isActive()) {
325 Log.w(TAG, "getExtractedText on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800326 callback.setExtractedText(null, callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 return;
328 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800329 callback.setExtractedText(ic.getExtractedText(
330 (ExtractedTextRequest)args.arg1, msg.arg1), callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 } catch (RemoteException e) {
332 Log.w(TAG, "Got RemoteException calling setExtractedText", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800333 } finally {
334 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 }
336 return;
337 }
338 case DO_COMMIT_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700339 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 if (ic == null || !isActive()) {
341 Log.w(TAG, "commitText on inactive InputConnection");
342 return;
343 }
344 ic.commitText((CharSequence)msg.obj, msg.arg1);
Yohei Yukawa159dd472016-01-07 16:52:33 -0800345 onUserAction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 return;
347 }
348 case DO_SET_SELECTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700349 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800350 if (ic == null || !isActive()) {
351 Log.w(TAG, "setSelection on inactive InputConnection");
352 return;
353 }
354 ic.setSelection(msg.arg1, msg.arg2);
355 return;
356 }
357 case DO_PERFORM_EDITOR_ACTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700358 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359 if (ic == null || !isActive()) {
360 Log.w(TAG, "performEditorAction on inactive InputConnection");
361 return;
362 }
363 ic.performEditorAction(msg.arg1);
364 return;
365 }
366 case DO_PERFORM_CONTEXT_MENU_ACTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700367 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368 if (ic == null || !isActive()) {
369 Log.w(TAG, "performContextMenuAction on inactive InputConnection");
370 return;
371 }
372 ic.performContextMenuAction(msg.arg1);
373 return;
374 }
375 case DO_COMMIT_COMPLETION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700376 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 if (ic == null || !isActive()) {
378 Log.w(TAG, "commitCompletion on inactive InputConnection");
379 return;
380 }
381 ic.commitCompletion((CompletionInfo)msg.obj);
382 return;
383 }
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800384 case DO_COMMIT_CORRECTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700385 InputConnection ic = getInputConnection();
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800386 if (ic == null || !isActive()) {
387 Log.w(TAG, "commitCorrection on inactive InputConnection");
388 return;
389 }
390 ic.commitCorrection((CorrectionInfo)msg.obj);
391 return;
392 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 case DO_SET_COMPOSING_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700394 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 if (ic == null || !isActive()) {
396 Log.w(TAG, "setComposingText on inactive InputConnection");
397 return;
398 }
399 ic.setComposingText((CharSequence)msg.obj, msg.arg1);
Yohei Yukawa159dd472016-01-07 16:52:33 -0800400 onUserAction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 return;
402 }
Amith Yamasania90b7f02010-08-25 18:27:20 -0700403 case DO_SET_COMPOSING_REGION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700404 InputConnection ic = getInputConnection();
Amith Yamasania90b7f02010-08-25 18:27:20 -0700405 if (ic == null || !isActive()) {
406 Log.w(TAG, "setComposingRegion on inactive InputConnection");
407 return;
408 }
409 ic.setComposingRegion(msg.arg1, msg.arg2);
410 return;
411 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 case DO_FINISH_COMPOSING_TEXT: {
Yohei Yukawa77e51832017-02-12 20:08:13 -0800413 if (isFinished()) {
414 // In this case, #finishComposingText() is guaranteed to be called already.
415 // There should be no negative impact if we ignore this call silently.
416 if (DEBUG) {
417 Log.w(TAG, "Bug 35301295: Redundant finishComposingText.");
418 }
419 return;
420 }
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700421 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 // Note we do NOT check isActive() here, because this is safe
423 // for an IME to call at any time, and we need to allow it
424 // through to clean up our state after the IME has switched to
425 // another client.
426 if (ic == null) {
427 Log.w(TAG, "finishComposingText on inactive InputConnection");
428 return;
429 }
430 ic.finishComposingText();
431 return;
432 }
433 case DO_SEND_KEY_EVENT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700434 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435 if (ic == null || !isActive()) {
436 Log.w(TAG, "sendKeyEvent on inactive InputConnection");
437 return;
438 }
439 ic.sendKeyEvent((KeyEvent)msg.obj);
Yohei Yukawa159dd472016-01-07 16:52:33 -0800440 onUserAction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 return;
442 }
443 case DO_CLEAR_META_KEY_STATES: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700444 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800445 if (ic == null || !isActive()) {
446 Log.w(TAG, "clearMetaKeyStates on inactive InputConnection");
447 return;
448 }
449 ic.clearMetaKeyStates(msg.arg1);
450 return;
451 }
452 case DO_DELETE_SURROUNDING_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700453 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800454 if (ic == null || !isActive()) {
455 Log.w(TAG, "deleteSurroundingText on inactive InputConnection");
456 return;
457 }
458 ic.deleteSurroundingText(msg.arg1, msg.arg2);
459 return;
460 }
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800461 case DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700462 InputConnection ic = getInputConnection();
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800463 if (ic == null || !isActive()) {
464 Log.w(TAG, "deleteSurroundingTextInCodePoints on inactive InputConnection");
465 return;
466 }
467 ic.deleteSurroundingTextInCodePoints(msg.arg1, msg.arg2);
468 return;
469 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 case DO_BEGIN_BATCH_EDIT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700471 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472 if (ic == null || !isActive()) {
473 Log.w(TAG, "beginBatchEdit on inactive InputConnection");
474 return;
475 }
476 ic.beginBatchEdit();
477 return;
478 }
479 case DO_END_BATCH_EDIT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700480 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481 if (ic == null || !isActive()) {
482 Log.w(TAG, "endBatchEdit on inactive InputConnection");
483 return;
484 }
485 ic.endBatchEdit();
486 return;
487 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 case DO_PERFORM_PRIVATE_COMMAND: {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800489 final SomeArgs args = (SomeArgs) msg.obj;
490 try {
491 final String action = (String) args.arg1;
492 final Bundle data = (Bundle) args.arg2;
493 InputConnection ic = getInputConnection();
494 if (ic == null || !isActive()) {
495 Log.w(TAG, "performPrivateCommand on inactive InputConnection");
496 return;
497 }
498 ic.performPrivateCommand(action, data);
499 } finally {
500 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 }
Yohei Yukawa3dd5fbc2017-02-22 20:49:10 -0800502 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800503 }
Yohei Yukawaa277db22014-08-21 18:38:44 -0700504 case DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO: {
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900505 SomeArgs args = (SomeArgs)msg.obj;
506 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800507 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
508 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700509 InputConnection ic = getInputConnection();
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900510 if (ic == null || !isActive()) {
511 Log.w(TAG, "requestCursorAnchorInfo on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800512 callback.setRequestUpdateCursorAnchorInfoResult(false, callbackSeq);
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900513 return;
514 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800515 callback.setRequestUpdateCursorAnchorInfoResult(
516 ic.requestCursorUpdates(msg.arg1), callbackSeq);
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900517 } catch (RemoteException e) {
518 Log.w(TAG, "Got RemoteException calling requestCursorAnchorInfo", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800519 } finally {
520 args.recycle();
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900521 }
522 return;
523 }
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700524 case DO_CLOSE_CONNECTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700525 // Note that we do not need to worry about race condition here, because 1) mFinished
526 // is updated only inside this block, and 2) the code here is running on a Handler
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700527 // hence we assume multiple DO_CLOSE_CONNECTION messages will not be handled at the
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700528 // same time.
529 if (isFinished()) {
530 return;
531 }
532 try {
533 InputConnection ic = getInputConnection();
534 // Note we do NOT check isActive() here, because this is safe
535 // for an IME to call at any time, and we need to allow it
536 // through to clean up our state after the IME has switched to
537 // another client.
538 if (ic == null) {
539 return;
540 }
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700541 @MissingMethodFlags
542 final int missingMethods = InputConnectionInspector.getMissingMethodFlags(ic);
543 if ((missingMethods & MissingMethodFlags.CLOSE_CONNECTION) == 0) {
544 ic.closeConnection();
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700545 }
546 } finally {
547 synchronized (mLock) {
548 mInputConnection = null;
549 mFinished = true;
550 }
551 }
552 return;
553 }
Yohei Yukawaadebb522016-06-17 10:10:39 -0700554 case DO_COMMIT_CONTENT: {
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700555 final int flags = msg.arg1;
Yohei Yukawa152944f2016-06-10 19:04:34 -0700556 SomeArgs args = (SomeArgs) msg.obj;
557 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800558 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
559 final int callbackSeq = args.argi6;
Yohei Yukawa152944f2016-06-10 19:04:34 -0700560 InputConnection ic = getInputConnection();
561 if (ic == null || !isActive()) {
Yohei Yukawaadebb522016-06-17 10:10:39 -0700562 Log.w(TAG, "commitContent on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800563 callback.setCommitContentResult(false, callbackSeq);
Yohei Yukawa152944f2016-06-10 19:04:34 -0700564 return;
565 }
566 final InputContentInfo inputContentInfo = (InputContentInfo) args.arg1;
567 if (inputContentInfo == null || !inputContentInfo.validate()) {
Yohei Yukawaadebb522016-06-17 10:10:39 -0700568 Log.w(TAG, "commitContent with invalid inputContentInfo="
Yohei Yukawa152944f2016-06-10 19:04:34 -0700569 + inputContentInfo);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800570 callback.setCommitContentResult(false, callbackSeq);
Yohei Yukawa152944f2016-06-10 19:04:34 -0700571 return;
572 }
Yohei Yukawaf3806f52016-06-30 16:27:46 -0700573 final boolean result =
574 ic.commitContent(inputContentInfo, flags, (Bundle) args.arg2);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800575 callback.setCommitContentResult(result, callbackSeq);
Yohei Yukawa152944f2016-06-10 19:04:34 -0700576 } catch (RemoteException e) {
Yohei Yukawaadebb522016-06-17 10:10:39 -0700577 Log.w(TAG, "Got RemoteException calling commitContent", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800578 } finally {
579 args.recycle();
Yohei Yukawa152944f2016-06-10 19:04:34 -0700580 }
581 return;
582 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583 }
584 Log.w(TAG, "Unhandled message code: " + msg.what);
585 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 Message obtainMessage(int what) {
588 return mH.obtainMessage(what);
589 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800590
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800591 Message obtainMessageII(int what, int arg1, int arg2) {
592 return mH.obtainMessage(what, arg1, arg2);
593 }
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595 Message obtainMessageO(int what, Object arg1) {
596 return mH.obtainMessage(what, 0, 0, arg1);
597 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800598
599 Message obtainMessageISC(int what, int arg1, int callbackSeq, IInputContextCallback callback) {
600 final SomeArgs args = SomeArgs.obtain();
601 args.arg6 = callback;
602 args.argi6 = callbackSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 return mH.obtainMessage(what, arg1, 0, args);
604 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800605
606 Message obtainMessageIISC(int what, int arg1, int arg2, int callbackSeq,
607 IInputContextCallback callback) {
608 final SomeArgs args = SomeArgs.obtain();
609 args.arg6 = callback;
610 args.argi6 = callbackSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611 return mH.obtainMessage(what, arg1, arg2, args);
612 }
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900613
Yohei Yukawace82eb22017-02-12 23:16:47 -0800614 Message obtainMessageIOOSC(int what, int arg1, Object objArg1, Object objArg2, int callbackSeq,
Yohei Yukawa152944f2016-06-10 19:04:34 -0700615 IInputContextCallback callback) {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800616 final SomeArgs args = SomeArgs.obtain();
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700617 args.arg1 = objArg1;
618 args.arg2 = objArg2;
Yohei Yukawace82eb22017-02-12 23:16:47 -0800619 args.arg6 = callback;
620 args.argi6 = callbackSeq;
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700621 return mH.obtainMessage(what, arg1, 0, args);
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900622 }
623
Yohei Yukawace82eb22017-02-12 23:16:47 -0800624 Message obtainMessageIOSC(int what, int arg1, Object arg2, int callbackSeq,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800625 IInputContextCallback callback) {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800626 final SomeArgs args = SomeArgs.obtain();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800627 args.arg1 = arg2;
Yohei Yukawace82eb22017-02-12 23:16:47 -0800628 args.arg6 = callback;
629 args.argi6 = callbackSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800630 return mH.obtainMessage(what, arg1, 0, args);
631 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800633 Message obtainMessageIO(int what, int arg1, Object arg2) {
634 return mH.obtainMessage(what, arg1, 0, arg2);
635 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800637 Message obtainMessageOO(int what, Object arg1, Object arg2) {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800638 final SomeArgs args = SomeArgs.obtain();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800639 args.arg1 = arg1;
640 args.arg2 = arg2;
641 return mH.obtainMessage(what, 0, 0, args);
642 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800643}