blob: 9de1b21c9bb3d37ed86d1d32498d3af5e7b131ef [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;
20
21import android.annotation.NonNull;
22import android.annotation.Nullable;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import android.os.Bundle;
24import android.os.Handler;
25import android.os.Looper;
26import android.os.Message;
27import android.os.RemoteException;
28import android.util.Log;
29import android.view.KeyEvent;
30import android.view.inputmethod.CompletionInfo;
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -080031import android.view.inputmethod.CorrectionInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.view.inputmethod.ExtractedTextRequest;
33import android.view.inputmethod.InputConnection;
Yohei Yukawa9f9afe522016-03-30 12:03:51 -070034import android.view.inputmethod.InputConnectionInspector;
35import android.view.inputmethod.InputConnectionInspector.MissingMethodFlags;
Yohei Yukawa152944f2016-06-10 19:04:34 -070036import android.view.inputmethod.InputContentInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037
Yohei Yukawa159dd472016-01-07 16:52:33 -080038public abstract class IInputConnectionWrapper extends IInputContext.Stub {
Yohei Yukawa77e51832017-02-12 20:08:13 -080039 private static final String TAG = "IInputConnectionWrapper";
40 private static final boolean DEBUG = false;
Amith Yamasania90b7f02010-08-25 18:27:20 -070041
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042 private static final int DO_GET_TEXT_AFTER_CURSOR = 10;
43 private static final int DO_GET_TEXT_BEFORE_CURSOR = 20;
Amith Yamasania90b7f02010-08-25 18:27:20 -070044 private static final int DO_GET_SELECTED_TEXT = 25;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045 private static final int DO_GET_CURSOR_CAPS_MODE = 30;
46 private static final int DO_GET_EXTRACTED_TEXT = 40;
47 private static final int DO_COMMIT_TEXT = 50;
48 private static final int DO_COMMIT_COMPLETION = 55;
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -080049 private static final int DO_COMMIT_CORRECTION = 56;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050 private static final int DO_SET_SELECTION = 57;
51 private static final int DO_PERFORM_EDITOR_ACTION = 58;
52 private static final int DO_PERFORM_CONTEXT_MENU_ACTION = 59;
53 private static final int DO_SET_COMPOSING_TEXT = 60;
Amith Yamasania90b7f02010-08-25 18:27:20 -070054 private static final int DO_SET_COMPOSING_REGION = 63;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055 private static final int DO_FINISH_COMPOSING_TEXT = 65;
56 private static final int DO_SEND_KEY_EVENT = 70;
57 private static final int DO_DELETE_SURROUNDING_TEXT = 80;
Yohei Yukawac89e22a2016-01-13 22:48:14 -080058 private static final int DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS = 81;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059 private static final int DO_BEGIN_BATCH_EDIT = 90;
60 private static final int DO_END_BATCH_EDIT = 95;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061 private static final int DO_PERFORM_PRIVATE_COMMAND = 120;
62 private static final int DO_CLEAR_META_KEY_STATES = 130;
Yohei Yukawaa277db22014-08-21 18:38:44 -070063 private static final int DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO = 140;
Yohei Yukawa9f9afe522016-03-30 12:03:51 -070064 private static final int DO_CLOSE_CONNECTION = 150;
Yohei Yukawaadebb522016-06-17 10:10:39 -070065 private static final int DO_COMMIT_CONTENT = 160;
Amith Yamasania90b7f02010-08-25 18:27:20 -070066
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070067 @GuardedBy("mLock")
68 @Nullable
69 private InputConnection mInputConnection;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070
71 private Looper mMainLooper;
72 private Handler mH;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070073 private Object mLock = new Object();
74 @GuardedBy("mLock")
75 private boolean mFinished = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076
77 static class SomeArgs {
78 Object arg1;
79 Object arg2;
80 IInputContextCallback callback;
81 int seq;
82 }
83
84 class MyHandler extends Handler {
85 MyHandler(Looper looper) {
86 super(looper);
87 }
88
89 @Override
90 public void handleMessage(Message msg) {
91 executeMessage(msg);
92 }
93 }
94
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070095 public IInputConnectionWrapper(Looper mainLooper, @NonNull InputConnection inputConnection) {
96 mInputConnection = inputConnection;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 mMainLooper = mainLooper;
98 mH = new MyHandler(mMainLooper);
99 }
100
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700101 @Nullable
102 public InputConnection getInputConnection() {
103 synchronized (mLock) {
104 return mInputConnection;
105 }
106 }
107
108 protected boolean isFinished() {
109 synchronized (mLock) {
110 return mFinished;
111 }
112 }
113
Yohei Yukawa159dd472016-01-07 16:52:33 -0800114 abstract protected boolean isActive();
115
116 /**
117 * Called when the user took some actions that should be taken into consideration to update the
118 * LRU list for input method rotation.
119 */
120 abstract protected void onUserAction();
121
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122 public void getTextAfterCursor(int length, int flags, int seq, IInputContextCallback callback) {
123 dispatchMessage(obtainMessageIISC(DO_GET_TEXT_AFTER_CURSOR, length, flags, seq, callback));
124 }
125
126 public void getTextBeforeCursor(int length, int flags, int seq, IInputContextCallback callback) {
127 dispatchMessage(obtainMessageIISC(DO_GET_TEXT_BEFORE_CURSOR, length, flags, seq, callback));
128 }
129
Amith Yamasania90b7f02010-08-25 18:27:20 -0700130 public void getSelectedText(int flags, int seq, IInputContextCallback callback) {
131 dispatchMessage(obtainMessageISC(DO_GET_SELECTED_TEXT, flags, seq, callback));
132 }
133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 public void getCursorCapsMode(int reqModes, int seq, IInputContextCallback callback) {
135 dispatchMessage(obtainMessageISC(DO_GET_CURSOR_CAPS_MODE, reqModes, seq, callback));
136 }
137
138 public void getExtractedText(ExtractedTextRequest request,
139 int flags, int seq, IInputContextCallback callback) {
140 dispatchMessage(obtainMessageIOSC(DO_GET_EXTRACTED_TEXT, flags,
141 request, seq, callback));
142 }
143
144 public void commitText(CharSequence text, int newCursorPosition) {
145 dispatchMessage(obtainMessageIO(DO_COMMIT_TEXT, newCursorPosition, text));
146 }
147
148 public void commitCompletion(CompletionInfo text) {
149 dispatchMessage(obtainMessageO(DO_COMMIT_COMPLETION, text));
150 }
151
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800152 public void commitCorrection(CorrectionInfo info) {
153 dispatchMessage(obtainMessageO(DO_COMMIT_CORRECTION, info));
154 }
155
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 public void setSelection(int start, int end) {
157 dispatchMessage(obtainMessageII(DO_SET_SELECTION, start, end));
158 }
159
160 public void performEditorAction(int id) {
161 dispatchMessage(obtainMessageII(DO_PERFORM_EDITOR_ACTION, id, 0));
162 }
163
164 public void performContextMenuAction(int id) {
165 dispatchMessage(obtainMessageII(DO_PERFORM_CONTEXT_MENU_ACTION, id, 0));
166 }
167
Amith Yamasania90b7f02010-08-25 18:27:20 -0700168 public void setComposingRegion(int start, int end) {
169 dispatchMessage(obtainMessageII(DO_SET_COMPOSING_REGION, start, end));
170 }
171
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 public void setComposingText(CharSequence text, int newCursorPosition) {
173 dispatchMessage(obtainMessageIO(DO_SET_COMPOSING_TEXT, newCursorPosition, text));
174 }
175
176 public void finishComposingText() {
177 dispatchMessage(obtainMessage(DO_FINISH_COMPOSING_TEXT));
178 }
179
180 public void sendKeyEvent(KeyEvent event) {
181 dispatchMessage(obtainMessageO(DO_SEND_KEY_EVENT, event));
182 }
183
184 public void clearMetaKeyStates(int states) {
185 dispatchMessage(obtainMessageII(DO_CLEAR_META_KEY_STATES, states, 0));
186 }
187
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800188 public void deleteSurroundingText(int beforeLength, int afterLength) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 dispatchMessage(obtainMessageII(DO_DELETE_SURROUNDING_TEXT,
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800190 beforeLength, afterLength));
191 }
192
193 public void deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
194 dispatchMessage(obtainMessageII(DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS,
195 beforeLength, afterLength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196 }
197
198 public void beginBatchEdit() {
199 dispatchMessage(obtainMessage(DO_BEGIN_BATCH_EDIT));
200 }
201
202 public void endBatchEdit() {
203 dispatchMessage(obtainMessage(DO_END_BATCH_EDIT));
204 }
205
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 public void performPrivateCommand(String action, Bundle data) {
207 dispatchMessage(obtainMessageOO(DO_PERFORM_PRIVATE_COMMAND, action, data));
208 }
satokadb43582011-03-09 10:08:47 +0900209
Yohei Yukawaa277db22014-08-21 18:38:44 -0700210 public void requestUpdateCursorAnchorInfo(int cursorUpdateMode, int seq,
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900211 IInputContextCallback callback) {
Yohei Yukawaa277db22014-08-21 18:38:44 -0700212 dispatchMessage(obtainMessageISC(DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO, cursorUpdateMode,
213 seq, callback));
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900214 }
215
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700216 public void closeConnection() {
217 dispatchMessage(obtainMessage(DO_CLOSE_CONNECTION));
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700218 }
219
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700220 public void commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts,
Yohei Yukawa152944f2016-06-10 19:04:34 -0700221 int seq, IInputContextCallback callback) {
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700222 dispatchMessage(obtainMessageIOOSC(DO_COMMIT_CONTENT, flags, inputContentInfo, opts, seq,
223 callback));
Yohei Yukawa152944f2016-06-10 19:04:34 -0700224 }
225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800226 void dispatchMessage(Message msg) {
227 // If we are calling this from the main thread, then we can call
228 // right through. Otherwise, we need to send the message to the
229 // main thread.
230 if (Looper.myLooper() == mMainLooper) {
231 executeMessage(msg);
232 msg.recycle();
233 return;
234 }
235
236 mH.sendMessage(msg);
237 }
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700238
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 void executeMessage(Message msg) {
240 switch (msg.what) {
241 case DO_GET_TEXT_AFTER_CURSOR: {
242 SomeArgs args = (SomeArgs)msg.obj;
243 try {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700244 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 if (ic == null || !isActive()) {
246 Log.w(TAG, "getTextAfterCursor on inactive InputConnection");
247 args.callback.setTextAfterCursor(null, args.seq);
248 return;
249 }
250 args.callback.setTextAfterCursor(ic.getTextAfterCursor(
251 msg.arg1, msg.arg2), args.seq);
252 } catch (RemoteException e) {
253 Log.w(TAG, "Got RemoteException calling setTextAfterCursor", e);
254 }
255 return;
256 }
257 case DO_GET_TEXT_BEFORE_CURSOR: {
258 SomeArgs args = (SomeArgs)msg.obj;
259 try {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700260 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 if (ic == null || !isActive()) {
262 Log.w(TAG, "getTextBeforeCursor on inactive InputConnection");
263 args.callback.setTextBeforeCursor(null, args.seq);
264 return;
265 }
266 args.callback.setTextBeforeCursor(ic.getTextBeforeCursor(
267 msg.arg1, msg.arg2), args.seq);
268 } catch (RemoteException e) {
269 Log.w(TAG, "Got RemoteException calling setTextBeforeCursor", e);
270 }
271 return;
272 }
Amith Yamasania90b7f02010-08-25 18:27:20 -0700273 case DO_GET_SELECTED_TEXT: {
274 SomeArgs args = (SomeArgs)msg.obj;
275 try {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700276 InputConnection ic = getInputConnection();
Amith Yamasania90b7f02010-08-25 18:27:20 -0700277 if (ic == null || !isActive()) {
278 Log.w(TAG, "getSelectedText on inactive InputConnection");
279 args.callback.setSelectedText(null, args.seq);
280 return;
281 }
282 args.callback.setSelectedText(ic.getSelectedText(
283 msg.arg1), args.seq);
284 } catch (RemoteException e) {
285 Log.w(TAG, "Got RemoteException calling setSelectedText", e);
286 }
287 return;
288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289 case DO_GET_CURSOR_CAPS_MODE: {
290 SomeArgs args = (SomeArgs)msg.obj;
291 try {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700292 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293 if (ic == null || !isActive()) {
294 Log.w(TAG, "getCursorCapsMode on inactive InputConnection");
295 args.callback.setCursorCapsMode(0, args.seq);
296 return;
297 }
298 args.callback.setCursorCapsMode(ic.getCursorCapsMode(msg.arg1),
299 args.seq);
300 } catch (RemoteException e) {
301 Log.w(TAG, "Got RemoteException calling setCursorCapsMode", e);
302 }
303 return;
304 }
305 case DO_GET_EXTRACTED_TEXT: {
306 SomeArgs args = (SomeArgs)msg.obj;
307 try {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700308 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 if (ic == null || !isActive()) {
310 Log.w(TAG, "getExtractedText on inactive InputConnection");
311 args.callback.setExtractedText(null, args.seq);
312 return;
313 }
314 args.callback.setExtractedText(ic.getExtractedText(
315 (ExtractedTextRequest)args.arg1, msg.arg1), args.seq);
316 } catch (RemoteException e) {
317 Log.w(TAG, "Got RemoteException calling setExtractedText", e);
318 }
319 return;
320 }
321 case DO_COMMIT_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700322 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 if (ic == null || !isActive()) {
324 Log.w(TAG, "commitText on inactive InputConnection");
325 return;
326 }
327 ic.commitText((CharSequence)msg.obj, msg.arg1);
Yohei Yukawa159dd472016-01-07 16:52:33 -0800328 onUserAction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 return;
330 }
331 case DO_SET_SELECTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700332 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 if (ic == null || !isActive()) {
334 Log.w(TAG, "setSelection on inactive InputConnection");
335 return;
336 }
337 ic.setSelection(msg.arg1, msg.arg2);
338 return;
339 }
340 case DO_PERFORM_EDITOR_ACTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700341 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 if (ic == null || !isActive()) {
343 Log.w(TAG, "performEditorAction on inactive InputConnection");
344 return;
345 }
346 ic.performEditorAction(msg.arg1);
347 return;
348 }
349 case DO_PERFORM_CONTEXT_MENU_ACTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700350 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800351 if (ic == null || !isActive()) {
352 Log.w(TAG, "performContextMenuAction on inactive InputConnection");
353 return;
354 }
355 ic.performContextMenuAction(msg.arg1);
356 return;
357 }
358 case DO_COMMIT_COMPLETION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700359 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 if (ic == null || !isActive()) {
361 Log.w(TAG, "commitCompletion on inactive InputConnection");
362 return;
363 }
364 ic.commitCompletion((CompletionInfo)msg.obj);
365 return;
366 }
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800367 case DO_COMMIT_CORRECTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700368 InputConnection ic = getInputConnection();
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800369 if (ic == null || !isActive()) {
370 Log.w(TAG, "commitCorrection on inactive InputConnection");
371 return;
372 }
373 ic.commitCorrection((CorrectionInfo)msg.obj);
374 return;
375 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 case DO_SET_COMPOSING_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700377 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 if (ic == null || !isActive()) {
379 Log.w(TAG, "setComposingText on inactive InputConnection");
380 return;
381 }
382 ic.setComposingText((CharSequence)msg.obj, msg.arg1);
Yohei Yukawa159dd472016-01-07 16:52:33 -0800383 onUserAction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 return;
385 }
Amith Yamasania90b7f02010-08-25 18:27:20 -0700386 case DO_SET_COMPOSING_REGION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700387 InputConnection ic = getInputConnection();
Amith Yamasania90b7f02010-08-25 18:27:20 -0700388 if (ic == null || !isActive()) {
389 Log.w(TAG, "setComposingRegion on inactive InputConnection");
390 return;
391 }
392 ic.setComposingRegion(msg.arg1, msg.arg2);
393 return;
394 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 case DO_FINISH_COMPOSING_TEXT: {
Yohei Yukawa77e51832017-02-12 20:08:13 -0800396 if (isFinished()) {
397 // In this case, #finishComposingText() is guaranteed to be called already.
398 // There should be no negative impact if we ignore this call silently.
399 if (DEBUG) {
400 Log.w(TAG, "Bug 35301295: Redundant finishComposingText.");
401 }
402 return;
403 }
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700404 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 // Note we do NOT check isActive() here, because this is safe
406 // for an IME to call at any time, and we need to allow it
407 // through to clean up our state after the IME has switched to
408 // another client.
409 if (ic == null) {
410 Log.w(TAG, "finishComposingText on inactive InputConnection");
411 return;
412 }
413 ic.finishComposingText();
414 return;
415 }
416 case DO_SEND_KEY_EVENT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700417 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 if (ic == null || !isActive()) {
419 Log.w(TAG, "sendKeyEvent on inactive InputConnection");
420 return;
421 }
422 ic.sendKeyEvent((KeyEvent)msg.obj);
Yohei Yukawa159dd472016-01-07 16:52:33 -0800423 onUserAction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800424 return;
425 }
426 case DO_CLEAR_META_KEY_STATES: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700427 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 if (ic == null || !isActive()) {
429 Log.w(TAG, "clearMetaKeyStates on inactive InputConnection");
430 return;
431 }
432 ic.clearMetaKeyStates(msg.arg1);
433 return;
434 }
435 case DO_DELETE_SURROUNDING_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700436 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 if (ic == null || !isActive()) {
438 Log.w(TAG, "deleteSurroundingText on inactive InputConnection");
439 return;
440 }
441 ic.deleteSurroundingText(msg.arg1, msg.arg2);
442 return;
443 }
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800444 case DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700445 InputConnection ic = getInputConnection();
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800446 if (ic == null || !isActive()) {
447 Log.w(TAG, "deleteSurroundingTextInCodePoints on inactive InputConnection");
448 return;
449 }
450 ic.deleteSurroundingTextInCodePoints(msg.arg1, msg.arg2);
451 return;
452 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800453 case DO_BEGIN_BATCH_EDIT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700454 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800455 if (ic == null || !isActive()) {
456 Log.w(TAG, "beginBatchEdit on inactive InputConnection");
457 return;
458 }
459 ic.beginBatchEdit();
460 return;
461 }
462 case DO_END_BATCH_EDIT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700463 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464 if (ic == null || !isActive()) {
465 Log.w(TAG, "endBatchEdit on inactive InputConnection");
466 return;
467 }
468 ic.endBatchEdit();
469 return;
470 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 case DO_PERFORM_PRIVATE_COMMAND: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700472 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 if (ic == null || !isActive()) {
474 Log.w(TAG, "performPrivateCommand on inactive InputConnection");
475 return;
476 }
477 SomeArgs args = (SomeArgs)msg.obj;
478 ic.performPrivateCommand((String)args.arg1,
479 (Bundle)args.arg2);
480 return;
481 }
Yohei Yukawaa277db22014-08-21 18:38:44 -0700482 case DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO: {
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900483 SomeArgs args = (SomeArgs)msg.obj;
484 try {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700485 InputConnection ic = getInputConnection();
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900486 if (ic == null || !isActive()) {
487 Log.w(TAG, "requestCursorAnchorInfo on inactive InputConnection");
Yohei Yukawaa277db22014-08-21 18:38:44 -0700488 args.callback.setRequestUpdateCursorAnchorInfoResult(false, args.seq);
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900489 return;
490 }
Yohei Yukawaa277db22014-08-21 18:38:44 -0700491 args.callback.setRequestUpdateCursorAnchorInfoResult(
Yohei Yukawad8636ea2014-09-02 22:03:30 -0700492 ic.requestCursorUpdates(msg.arg1), args.seq);
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900493 } catch (RemoteException e) {
494 Log.w(TAG, "Got RemoteException calling requestCursorAnchorInfo", e);
495 }
496 return;
497 }
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700498 case DO_CLOSE_CONNECTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700499 // Note that we do not need to worry about race condition here, because 1) mFinished
500 // is updated only inside this block, and 2) the code here is running on a Handler
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700501 // hence we assume multiple DO_CLOSE_CONNECTION messages will not be handled at the
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700502 // same time.
503 if (isFinished()) {
504 return;
505 }
506 try {
507 InputConnection ic = getInputConnection();
508 // Note we do NOT check isActive() here, because this is safe
509 // for an IME to call at any time, and we need to allow it
510 // through to clean up our state after the IME has switched to
511 // another client.
512 if (ic == null) {
513 return;
514 }
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700515 @MissingMethodFlags
516 final int missingMethods = InputConnectionInspector.getMissingMethodFlags(ic);
517 if ((missingMethods & MissingMethodFlags.CLOSE_CONNECTION) == 0) {
518 ic.closeConnection();
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700519 }
520 } finally {
521 synchronized (mLock) {
522 mInputConnection = null;
523 mFinished = true;
524 }
525 }
526 return;
527 }
Yohei Yukawaadebb522016-06-17 10:10:39 -0700528 case DO_COMMIT_CONTENT: {
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700529 final int flags = msg.arg1;
Yohei Yukawa152944f2016-06-10 19:04:34 -0700530 SomeArgs args = (SomeArgs) msg.obj;
531 try {
532 InputConnection ic = getInputConnection();
533 if (ic == null || !isActive()) {
Yohei Yukawaadebb522016-06-17 10:10:39 -0700534 Log.w(TAG, "commitContent on inactive InputConnection");
535 args.callback.setCommitContentResult(false, args.seq);
Yohei Yukawa152944f2016-06-10 19:04:34 -0700536 return;
537 }
538 final InputContentInfo inputContentInfo = (InputContentInfo) args.arg1;
539 if (inputContentInfo == null || !inputContentInfo.validate()) {
Yohei Yukawaadebb522016-06-17 10:10:39 -0700540 Log.w(TAG, "commitContent with invalid inputContentInfo="
Yohei Yukawa152944f2016-06-10 19:04:34 -0700541 + inputContentInfo);
Yohei Yukawaadebb522016-06-17 10:10:39 -0700542 args.callback.setCommitContentResult(false, args.seq);
Yohei Yukawa152944f2016-06-10 19:04:34 -0700543 return;
544 }
Yohei Yukawaf3806f52016-06-30 16:27:46 -0700545 final boolean result =
546 ic.commitContent(inputContentInfo, flags, (Bundle) args.arg2);
Yohei Yukawaf3806f52016-06-30 16:27:46 -0700547 args.callback.setCommitContentResult(result, args.seq);
Yohei Yukawa152944f2016-06-10 19:04:34 -0700548 } catch (RemoteException e) {
Yohei Yukawaadebb522016-06-17 10:10:39 -0700549 Log.w(TAG, "Got RemoteException calling commitContent", e);
Yohei Yukawa152944f2016-06-10 19:04:34 -0700550 }
551 return;
552 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553 }
554 Log.w(TAG, "Unhandled message code: " + msg.what);
555 }
556
557 Message obtainMessage(int what) {
558 return mH.obtainMessage(what);
559 }
560
561 Message obtainMessageII(int what, int arg1, int arg2) {
562 return mH.obtainMessage(what, arg1, arg2);
563 }
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 Message obtainMessageO(int what, Object arg1) {
566 return mH.obtainMessage(what, 0, 0, arg1);
567 }
568
569 Message obtainMessageISC(int what, int arg1, int seq, IInputContextCallback callback) {
570 SomeArgs args = new SomeArgs();
571 args.callback = callback;
572 args.seq = seq;
573 return mH.obtainMessage(what, arg1, 0, args);
574 }
575
576 Message obtainMessageIISC(int what, int arg1, int arg2, int seq, IInputContextCallback callback) {
577 SomeArgs args = new SomeArgs();
578 args.callback = callback;
579 args.seq = seq;
580 return mH.obtainMessage(what, arg1, arg2, args);
581 }
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900582
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700583 Message obtainMessageIOOSC(int what, int arg1, Object objArg1, Object objArg2, int seq,
Yohei Yukawa152944f2016-06-10 19:04:34 -0700584 IInputContextCallback callback) {
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900585 SomeArgs args = new SomeArgs();
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700586 args.arg1 = objArg1;
587 args.arg2 = objArg2;
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900588 args.callback = callback;
589 args.seq = seq;
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700590 return mH.obtainMessage(what, arg1, 0, args);
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900591 }
592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 Message obtainMessageIOSC(int what, int arg1, Object arg2, int seq,
594 IInputContextCallback callback) {
595 SomeArgs args = new SomeArgs();
596 args.arg1 = arg2;
597 args.callback = callback;
598 args.seq = seq;
599 return mH.obtainMessage(what, arg1, 0, args);
600 }
601
602 Message obtainMessageIO(int what, int arg1, Object arg2) {
603 return mH.obtainMessage(what, arg1, 0, arg2);
604 }
605
606 Message obtainMessageOO(int what, Object arg1, Object arg2) {
607 SomeArgs args = new SomeArgs();
608 args.arg1 = arg1;
609 args.arg2 = arg2;
610 return mH.obtainMessage(what, 0, 0, args);
611 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612}