blob: 3a4afad3f3670a4e08c6030b80614e45abc9e09e [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;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036
Yohei Yukawa159dd472016-01-07 16:52:33 -080037public abstract class IInputConnectionWrapper extends IInputContext.Stub {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038 static final String TAG = "IInputConnectionWrapper";
Amith Yamasania90b7f02010-08-25 18:27:20 -070039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040 private static final int DO_GET_TEXT_AFTER_CURSOR = 10;
41 private static final int DO_GET_TEXT_BEFORE_CURSOR = 20;
Amith Yamasania90b7f02010-08-25 18:27:20 -070042 private static final int DO_GET_SELECTED_TEXT = 25;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043 private static final int DO_GET_CURSOR_CAPS_MODE = 30;
44 private static final int DO_GET_EXTRACTED_TEXT = 40;
45 private static final int DO_COMMIT_TEXT = 50;
46 private static final int DO_COMMIT_COMPLETION = 55;
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -080047 private static final int DO_COMMIT_CORRECTION = 56;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048 private static final int DO_SET_SELECTION = 57;
49 private static final int DO_PERFORM_EDITOR_ACTION = 58;
50 private static final int DO_PERFORM_CONTEXT_MENU_ACTION = 59;
51 private static final int DO_SET_COMPOSING_TEXT = 60;
Amith Yamasania90b7f02010-08-25 18:27:20 -070052 private static final int DO_SET_COMPOSING_REGION = 63;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053 private static final int DO_FINISH_COMPOSING_TEXT = 65;
54 private static final int DO_SEND_KEY_EVENT = 70;
55 private static final int DO_DELETE_SURROUNDING_TEXT = 80;
Yohei Yukawac89e22a2016-01-13 22:48:14 -080056 private static final int DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS = 81;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057 private static final int DO_BEGIN_BATCH_EDIT = 90;
58 private static final int DO_END_BATCH_EDIT = 95;
59 private static final int DO_REPORT_FULLSCREEN_MODE = 100;
60 private static final int DO_PERFORM_PRIVATE_COMMAND = 120;
61 private static final int DO_CLEAR_META_KEY_STATES = 130;
Yohei Yukawaa277db22014-08-21 18:38:44 -070062 private static final int DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO = 140;
Yohei Yukawa9f9afe522016-03-30 12:03:51 -070063 private static final int DO_CLOSE_CONNECTION = 150;
Amith Yamasania90b7f02010-08-25 18:27:20 -070064
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070065 @GuardedBy("mLock")
66 @Nullable
67 private InputConnection mInputConnection;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068
69 private Looper mMainLooper;
70 private Handler mH;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070071 private Object mLock = new Object();
72 @GuardedBy("mLock")
73 private boolean mFinished = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074
75 static class SomeArgs {
76 Object arg1;
77 Object arg2;
78 IInputContextCallback callback;
79 int seq;
80 }
81
82 class MyHandler extends Handler {
83 MyHandler(Looper looper) {
84 super(looper);
85 }
86
87 @Override
88 public void handleMessage(Message msg) {
89 executeMessage(msg);
90 }
91 }
92
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070093 public IInputConnectionWrapper(Looper mainLooper, @NonNull InputConnection inputConnection) {
94 mInputConnection = inputConnection;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 mMainLooper = mainLooper;
96 mH = new MyHandler(mMainLooper);
97 }
98
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070099 @Nullable
100 public InputConnection getInputConnection() {
101 synchronized (mLock) {
102 return mInputConnection;
103 }
104 }
105
106 protected boolean isFinished() {
107 synchronized (mLock) {
108 return mFinished;
109 }
110 }
111
Yohei Yukawa159dd472016-01-07 16:52:33 -0800112 abstract protected boolean isActive();
113
114 /**
115 * Called when the user took some actions that should be taken into consideration to update the
116 * LRU list for input method rotation.
117 */
118 abstract protected void onUserAction();
119
120 /**
121 * Called when the input method started or stopped full-screen mode.
122 *
123 */
124 abstract protected void onReportFullscreenMode(boolean enabled);
125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126 public void getTextAfterCursor(int length, int flags, int seq, IInputContextCallback callback) {
127 dispatchMessage(obtainMessageIISC(DO_GET_TEXT_AFTER_CURSOR, length, flags, seq, callback));
128 }
129
130 public void getTextBeforeCursor(int length, int flags, int seq, IInputContextCallback callback) {
131 dispatchMessage(obtainMessageIISC(DO_GET_TEXT_BEFORE_CURSOR, length, flags, seq, callback));
132 }
133
Amith Yamasania90b7f02010-08-25 18:27:20 -0700134 public void getSelectedText(int flags, int seq, IInputContextCallback callback) {
135 dispatchMessage(obtainMessageISC(DO_GET_SELECTED_TEXT, flags, seq, callback));
136 }
137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 public void getCursorCapsMode(int reqModes, int seq, IInputContextCallback callback) {
139 dispatchMessage(obtainMessageISC(DO_GET_CURSOR_CAPS_MODE, reqModes, seq, callback));
140 }
141
142 public void getExtractedText(ExtractedTextRequest request,
143 int flags, int seq, IInputContextCallback callback) {
144 dispatchMessage(obtainMessageIOSC(DO_GET_EXTRACTED_TEXT, flags,
145 request, seq, callback));
146 }
147
148 public void commitText(CharSequence text, int newCursorPosition) {
149 dispatchMessage(obtainMessageIO(DO_COMMIT_TEXT, newCursorPosition, text));
150 }
151
152 public void commitCompletion(CompletionInfo text) {
153 dispatchMessage(obtainMessageO(DO_COMMIT_COMPLETION, text));
154 }
155
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800156 public void commitCorrection(CorrectionInfo info) {
157 dispatchMessage(obtainMessageO(DO_COMMIT_CORRECTION, info));
158 }
159
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 public void setSelection(int start, int end) {
161 dispatchMessage(obtainMessageII(DO_SET_SELECTION, start, end));
162 }
163
164 public void performEditorAction(int id) {
165 dispatchMessage(obtainMessageII(DO_PERFORM_EDITOR_ACTION, id, 0));
166 }
167
168 public void performContextMenuAction(int id) {
169 dispatchMessage(obtainMessageII(DO_PERFORM_CONTEXT_MENU_ACTION, id, 0));
170 }
171
Amith Yamasania90b7f02010-08-25 18:27:20 -0700172 public void setComposingRegion(int start, int end) {
173 dispatchMessage(obtainMessageII(DO_SET_COMPOSING_REGION, start, end));
174 }
175
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176 public void setComposingText(CharSequence text, int newCursorPosition) {
177 dispatchMessage(obtainMessageIO(DO_SET_COMPOSING_TEXT, newCursorPosition, text));
178 }
179
180 public void finishComposingText() {
181 dispatchMessage(obtainMessage(DO_FINISH_COMPOSING_TEXT));
182 }
183
184 public void sendKeyEvent(KeyEvent event) {
185 dispatchMessage(obtainMessageO(DO_SEND_KEY_EVENT, event));
186 }
187
188 public void clearMetaKeyStates(int states) {
189 dispatchMessage(obtainMessageII(DO_CLEAR_META_KEY_STATES, states, 0));
190 }
191
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800192 public void deleteSurroundingText(int beforeLength, int afterLength) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193 dispatchMessage(obtainMessageII(DO_DELETE_SURROUNDING_TEXT,
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800194 beforeLength, afterLength));
195 }
196
197 public void deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
198 dispatchMessage(obtainMessageII(DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS,
199 beforeLength, afterLength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 }
201
202 public void beginBatchEdit() {
203 dispatchMessage(obtainMessage(DO_BEGIN_BATCH_EDIT));
204 }
205
206 public void endBatchEdit() {
207 dispatchMessage(obtainMessage(DO_END_BATCH_EDIT));
208 }
209
210 public void reportFullscreenMode(boolean enabled) {
211 dispatchMessage(obtainMessageII(DO_REPORT_FULLSCREEN_MODE, enabled ? 1 : 0, 0));
212 }
213
214 public void performPrivateCommand(String action, Bundle data) {
215 dispatchMessage(obtainMessageOO(DO_PERFORM_PRIVATE_COMMAND, action, data));
216 }
satokadb43582011-03-09 10:08:47 +0900217
Yohei Yukawaa277db22014-08-21 18:38:44 -0700218 public void requestUpdateCursorAnchorInfo(int cursorUpdateMode, int seq,
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900219 IInputContextCallback callback) {
Yohei Yukawaa277db22014-08-21 18:38:44 -0700220 dispatchMessage(obtainMessageISC(DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO, cursorUpdateMode,
221 seq, callback));
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900222 }
223
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700224 public void closeConnection() {
225 dispatchMessage(obtainMessage(DO_CLOSE_CONNECTION));
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700226 }
227
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800228 void dispatchMessage(Message msg) {
229 // If we are calling this from the main thread, then we can call
230 // right through. Otherwise, we need to send the message to the
231 // main thread.
232 if (Looper.myLooper() == mMainLooper) {
233 executeMessage(msg);
234 msg.recycle();
235 return;
236 }
237
238 mH.sendMessage(msg);
239 }
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 void executeMessage(Message msg) {
242 switch (msg.what) {
243 case DO_GET_TEXT_AFTER_CURSOR: {
244 SomeArgs args = (SomeArgs)msg.obj;
245 try {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700246 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 if (ic == null || !isActive()) {
248 Log.w(TAG, "getTextAfterCursor on inactive InputConnection");
249 args.callback.setTextAfterCursor(null, args.seq);
250 return;
251 }
252 args.callback.setTextAfterCursor(ic.getTextAfterCursor(
253 msg.arg1, msg.arg2), args.seq);
254 } catch (RemoteException e) {
255 Log.w(TAG, "Got RemoteException calling setTextAfterCursor", e);
256 }
257 return;
258 }
259 case DO_GET_TEXT_BEFORE_CURSOR: {
260 SomeArgs args = (SomeArgs)msg.obj;
261 try {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700262 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 if (ic == null || !isActive()) {
264 Log.w(TAG, "getTextBeforeCursor on inactive InputConnection");
265 args.callback.setTextBeforeCursor(null, args.seq);
266 return;
267 }
268 args.callback.setTextBeforeCursor(ic.getTextBeforeCursor(
269 msg.arg1, msg.arg2), args.seq);
270 } catch (RemoteException e) {
271 Log.w(TAG, "Got RemoteException calling setTextBeforeCursor", e);
272 }
273 return;
274 }
Amith Yamasania90b7f02010-08-25 18:27:20 -0700275 case DO_GET_SELECTED_TEXT: {
276 SomeArgs args = (SomeArgs)msg.obj;
277 try {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700278 InputConnection ic = getInputConnection();
Amith Yamasania90b7f02010-08-25 18:27:20 -0700279 if (ic == null || !isActive()) {
280 Log.w(TAG, "getSelectedText on inactive InputConnection");
281 args.callback.setSelectedText(null, args.seq);
282 return;
283 }
284 args.callback.setSelectedText(ic.getSelectedText(
285 msg.arg1), args.seq);
286 } catch (RemoteException e) {
287 Log.w(TAG, "Got RemoteException calling setSelectedText", e);
288 }
289 return;
290 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 case DO_GET_CURSOR_CAPS_MODE: {
292 SomeArgs args = (SomeArgs)msg.obj;
293 try {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700294 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800295 if (ic == null || !isActive()) {
296 Log.w(TAG, "getCursorCapsMode on inactive InputConnection");
297 args.callback.setCursorCapsMode(0, args.seq);
298 return;
299 }
300 args.callback.setCursorCapsMode(ic.getCursorCapsMode(msg.arg1),
301 args.seq);
302 } catch (RemoteException e) {
303 Log.w(TAG, "Got RemoteException calling setCursorCapsMode", e);
304 }
305 return;
306 }
307 case DO_GET_EXTRACTED_TEXT: {
308 SomeArgs args = (SomeArgs)msg.obj;
309 try {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700310 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 if (ic == null || !isActive()) {
312 Log.w(TAG, "getExtractedText on inactive InputConnection");
313 args.callback.setExtractedText(null, args.seq);
314 return;
315 }
316 args.callback.setExtractedText(ic.getExtractedText(
317 (ExtractedTextRequest)args.arg1, msg.arg1), args.seq);
318 } catch (RemoteException e) {
319 Log.w(TAG, "Got RemoteException calling setExtractedText", e);
320 }
321 return;
322 }
323 case DO_COMMIT_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700324 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325 if (ic == null || !isActive()) {
326 Log.w(TAG, "commitText on inactive InputConnection");
327 return;
328 }
329 ic.commitText((CharSequence)msg.obj, msg.arg1);
Yohei Yukawa159dd472016-01-07 16:52:33 -0800330 onUserAction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 return;
332 }
333 case DO_SET_SELECTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700334 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 if (ic == null || !isActive()) {
336 Log.w(TAG, "setSelection on inactive InputConnection");
337 return;
338 }
339 ic.setSelection(msg.arg1, msg.arg2);
340 return;
341 }
342 case DO_PERFORM_EDITOR_ACTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700343 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 if (ic == null || !isActive()) {
345 Log.w(TAG, "performEditorAction on inactive InputConnection");
346 return;
347 }
348 ic.performEditorAction(msg.arg1);
349 return;
350 }
351 case DO_PERFORM_CONTEXT_MENU_ACTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700352 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800353 if (ic == null || !isActive()) {
354 Log.w(TAG, "performContextMenuAction on inactive InputConnection");
355 return;
356 }
357 ic.performContextMenuAction(msg.arg1);
358 return;
359 }
360 case DO_COMMIT_COMPLETION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700361 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362 if (ic == null || !isActive()) {
363 Log.w(TAG, "commitCompletion on inactive InputConnection");
364 return;
365 }
366 ic.commitCompletion((CompletionInfo)msg.obj);
367 return;
368 }
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800369 case DO_COMMIT_CORRECTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700370 InputConnection ic = getInputConnection();
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800371 if (ic == null || !isActive()) {
372 Log.w(TAG, "commitCorrection on inactive InputConnection");
373 return;
374 }
375 ic.commitCorrection((CorrectionInfo)msg.obj);
376 return;
377 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 case DO_SET_COMPOSING_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700379 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 if (ic == null || !isActive()) {
381 Log.w(TAG, "setComposingText on inactive InputConnection");
382 return;
383 }
384 ic.setComposingText((CharSequence)msg.obj, msg.arg1);
Yohei Yukawa159dd472016-01-07 16:52:33 -0800385 onUserAction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 return;
387 }
Amith Yamasania90b7f02010-08-25 18:27:20 -0700388 case DO_SET_COMPOSING_REGION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700389 InputConnection ic = getInputConnection();
Amith Yamasania90b7f02010-08-25 18:27:20 -0700390 if (ic == null || !isActive()) {
391 Log.w(TAG, "setComposingRegion on inactive InputConnection");
392 return;
393 }
394 ic.setComposingRegion(msg.arg1, msg.arg2);
395 return;
396 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 case DO_FINISH_COMPOSING_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700398 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 // Note we do NOT check isActive() here, because this is safe
400 // for an IME to call at any time, and we need to allow it
401 // through to clean up our state after the IME has switched to
402 // another client.
403 if (ic == null) {
404 Log.w(TAG, "finishComposingText on inactive InputConnection");
405 return;
406 }
407 ic.finishComposingText();
408 return;
409 }
410 case DO_SEND_KEY_EVENT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700411 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 if (ic == null || !isActive()) {
413 Log.w(TAG, "sendKeyEvent on inactive InputConnection");
414 return;
415 }
416 ic.sendKeyEvent((KeyEvent)msg.obj);
Yohei Yukawa159dd472016-01-07 16:52:33 -0800417 onUserAction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 return;
419 }
420 case DO_CLEAR_META_KEY_STATES: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700421 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800422 if (ic == null || !isActive()) {
423 Log.w(TAG, "clearMetaKeyStates on inactive InputConnection");
424 return;
425 }
426 ic.clearMetaKeyStates(msg.arg1);
427 return;
428 }
429 case DO_DELETE_SURROUNDING_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700430 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 if (ic == null || !isActive()) {
432 Log.w(TAG, "deleteSurroundingText on inactive InputConnection");
433 return;
434 }
435 ic.deleteSurroundingText(msg.arg1, msg.arg2);
436 return;
437 }
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800438 case DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700439 InputConnection ic = getInputConnection();
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800440 if (ic == null || !isActive()) {
441 Log.w(TAG, "deleteSurroundingTextInCodePoints on inactive InputConnection");
442 return;
443 }
444 ic.deleteSurroundingTextInCodePoints(msg.arg1, msg.arg2);
445 return;
446 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447 case DO_BEGIN_BATCH_EDIT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700448 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 if (ic == null || !isActive()) {
450 Log.w(TAG, "beginBatchEdit on inactive InputConnection");
451 return;
452 }
453 ic.beginBatchEdit();
454 return;
455 }
456 case DO_END_BATCH_EDIT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700457 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800458 if (ic == null || !isActive()) {
459 Log.w(TAG, "endBatchEdit on inactive InputConnection");
460 return;
461 }
462 ic.endBatchEdit();
463 return;
464 }
465 case DO_REPORT_FULLSCREEN_MODE: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700466 InputConnection ic = getInputConnection();
Andrei Stingaceanuda589df2015-06-17 10:38:08 +0100467 if (ic == null) {
468 Log.w(TAG, "reportFullscreenMode on inexistent InputConnection");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469 return;
470 }
Yohei Yukawa159dd472016-01-07 16:52:33 -0800471 final boolean enabled = msg.arg1 == 1;
472 ic.reportFullscreenMode(enabled);
473 onReportFullscreenMode(enabled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 return;
475 }
476 case DO_PERFORM_PRIVATE_COMMAND: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700477 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 if (ic == null || !isActive()) {
479 Log.w(TAG, "performPrivateCommand on inactive InputConnection");
480 return;
481 }
482 SomeArgs args = (SomeArgs)msg.obj;
483 ic.performPrivateCommand((String)args.arg1,
484 (Bundle)args.arg2);
485 return;
486 }
Yohei Yukawaa277db22014-08-21 18:38:44 -0700487 case DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO: {
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900488 SomeArgs args = (SomeArgs)msg.obj;
489 try {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700490 InputConnection ic = getInputConnection();
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900491 if (ic == null || !isActive()) {
492 Log.w(TAG, "requestCursorAnchorInfo on inactive InputConnection");
Yohei Yukawaa277db22014-08-21 18:38:44 -0700493 args.callback.setRequestUpdateCursorAnchorInfoResult(false, args.seq);
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900494 return;
495 }
Yohei Yukawaa277db22014-08-21 18:38:44 -0700496 args.callback.setRequestUpdateCursorAnchorInfoResult(
Yohei Yukawad8636ea2014-09-02 22:03:30 -0700497 ic.requestCursorUpdates(msg.arg1), args.seq);
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900498 } catch (RemoteException e) {
499 Log.w(TAG, "Got RemoteException calling requestCursorAnchorInfo", e);
500 }
501 return;
502 }
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700503 case DO_CLOSE_CONNECTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700504 // Note that we do not need to worry about race condition here, because 1) mFinished
505 // is updated only inside this block, and 2) the code here is running on a Handler
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700506 // hence we assume multiple DO_CLOSE_CONNECTION messages will not be handled at the
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700507 // same time.
508 if (isFinished()) {
509 return;
510 }
511 try {
512 InputConnection ic = getInputConnection();
513 // Note we do NOT check isActive() here, because this is safe
514 // for an IME to call at any time, and we need to allow it
515 // through to clean up our state after the IME has switched to
516 // another client.
517 if (ic == null) {
518 return;
519 }
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700520 @MissingMethodFlags
521 final int missingMethods = InputConnectionInspector.getMissingMethodFlags(ic);
522 if ((missingMethods & MissingMethodFlags.CLOSE_CONNECTION) == 0) {
523 ic.closeConnection();
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700524 }
525 } finally {
526 synchronized (mLock) {
527 mInputConnection = null;
528 mFinished = true;
529 }
530 }
531 return;
532 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533 }
534 Log.w(TAG, "Unhandled message code: " + msg.what);
535 }
536
537 Message obtainMessage(int what) {
538 return mH.obtainMessage(what);
539 }
540
541 Message obtainMessageII(int what, int arg1, int arg2) {
542 return mH.obtainMessage(what, arg1, arg2);
543 }
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545 Message obtainMessageO(int what, Object arg1) {
546 return mH.obtainMessage(what, 0, 0, arg1);
547 }
548
549 Message obtainMessageISC(int what, int arg1, int seq, IInputContextCallback callback) {
550 SomeArgs args = new SomeArgs();
551 args.callback = callback;
552 args.seq = seq;
553 return mH.obtainMessage(what, arg1, 0, args);
554 }
555
556 Message obtainMessageIISC(int what, int arg1, int arg2, int seq, IInputContextCallback callback) {
557 SomeArgs args = new SomeArgs();
558 args.callback = callback;
559 args.seq = seq;
560 return mH.obtainMessage(what, arg1, arg2, args);
561 }
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900562
563 Message obtainMessageOSC(int what, Object arg1, int seq, IInputContextCallback callback) {
564 SomeArgs args = new SomeArgs();
565 args.arg1 = arg1;
566 args.callback = callback;
567 args.seq = seq;
568 return mH.obtainMessage(what, 0, 0, args);
569 }
570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800571 Message obtainMessageIOSC(int what, int arg1, Object arg2, int seq,
572 IInputContextCallback callback) {
573 SomeArgs args = new SomeArgs();
574 args.arg1 = arg2;
575 args.callback = callback;
576 args.seq = seq;
577 return mH.obtainMessage(what, arg1, 0, args);
578 }
579
580 Message obtainMessageIO(int what, int arg1, Object arg2) {
581 return mH.obtainMessage(what, arg1, 0, arg2);
582 }
583
584 Message obtainMessageOO(int what, Object arg1, Object arg2) {
585 SomeArgs args = new SomeArgs();
586 args.arg1 = arg1;
587 args.arg2 = arg2;
588 return mH.obtainMessage(what, 0, 0, args);
589 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590}