blob: e08caa8e199d5ed0d215d1bb11296d716749167d [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;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.os.Bundle;
25import android.os.Handler;
Yohei Yukawae77386e2018-01-23 10:39:32 -080026import android.os.LocaleList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import 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;
Yohei Yukawae77386e2018-01-23 10:39:32 -080068 private static final int DO_REPORT_LANGUAGE_HINT = 170;
Amith Yamasania90b7f02010-08-25 18:27:20 -070069
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070070 @GuardedBy("mLock")
71 @Nullable
72 private InputConnection mInputConnection;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073
74 private Looper mMainLooper;
75 private Handler mH;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070076 private Object mLock = new Object();
77 @GuardedBy("mLock")
78 private boolean mFinished = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080 class MyHandler extends Handler {
81 MyHandler(Looper looper) {
82 super(looper);
83 }
84
85 @Override
86 public void handleMessage(Message msg) {
87 executeMessage(msg);
88 }
89 }
90
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070091 public IInputConnectionWrapper(Looper mainLooper, @NonNull InputConnection inputConnection) {
92 mInputConnection = inputConnection;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 mMainLooper = mainLooper;
94 mH = new MyHandler(mMainLooper);
95 }
96
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070097 @Nullable
98 public InputConnection getInputConnection() {
99 synchronized (mLock) {
100 return mInputConnection;
101 }
102 }
103
104 protected boolean isFinished() {
105 synchronized (mLock) {
106 return mFinished;
107 }
108 }
109
Yohei Yukawa159dd472016-01-07 16:52:33 -0800110 abstract protected boolean isActive();
111
112 /**
113 * Called when the user took some actions that should be taken into consideration to update the
114 * LRU list for input method rotation.
115 */
116 abstract protected void onUserAction();
117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118 public void getTextAfterCursor(int length, int flags, int seq, IInputContextCallback callback) {
119 dispatchMessage(obtainMessageIISC(DO_GET_TEXT_AFTER_CURSOR, length, flags, seq, callback));
120 }
121
122 public void getTextBeforeCursor(int length, int flags, int seq, IInputContextCallback callback) {
123 dispatchMessage(obtainMessageIISC(DO_GET_TEXT_BEFORE_CURSOR, length, flags, seq, callback));
124 }
125
Amith Yamasania90b7f02010-08-25 18:27:20 -0700126 public void getSelectedText(int flags, int seq, IInputContextCallback callback) {
127 dispatchMessage(obtainMessageISC(DO_GET_SELECTED_TEXT, flags, seq, callback));
128 }
129
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 public void getCursorCapsMode(int reqModes, int seq, IInputContextCallback callback) {
131 dispatchMessage(obtainMessageISC(DO_GET_CURSOR_CAPS_MODE, reqModes, seq, callback));
132 }
133
134 public void getExtractedText(ExtractedTextRequest request,
135 int flags, int seq, IInputContextCallback callback) {
136 dispatchMessage(obtainMessageIOSC(DO_GET_EXTRACTED_TEXT, flags,
137 request, seq, callback));
138 }
139
140 public void commitText(CharSequence text, int newCursorPosition) {
141 dispatchMessage(obtainMessageIO(DO_COMMIT_TEXT, newCursorPosition, text));
142 }
143
144 public void commitCompletion(CompletionInfo text) {
145 dispatchMessage(obtainMessageO(DO_COMMIT_COMPLETION, text));
146 }
147
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800148 public void commitCorrection(CorrectionInfo info) {
149 dispatchMessage(obtainMessageO(DO_COMMIT_CORRECTION, info));
150 }
151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 public void setSelection(int start, int end) {
153 dispatchMessage(obtainMessageII(DO_SET_SELECTION, start, end));
154 }
155
156 public void performEditorAction(int id) {
157 dispatchMessage(obtainMessageII(DO_PERFORM_EDITOR_ACTION, id, 0));
158 }
159
160 public void performContextMenuAction(int id) {
161 dispatchMessage(obtainMessageII(DO_PERFORM_CONTEXT_MENU_ACTION, id, 0));
162 }
163
Amith Yamasania90b7f02010-08-25 18:27:20 -0700164 public void setComposingRegion(int start, int end) {
165 dispatchMessage(obtainMessageII(DO_SET_COMPOSING_REGION, start, end));
166 }
167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 public void setComposingText(CharSequence text, int newCursorPosition) {
169 dispatchMessage(obtainMessageIO(DO_SET_COMPOSING_TEXT, newCursorPosition, text));
170 }
171
172 public void finishComposingText() {
173 dispatchMessage(obtainMessage(DO_FINISH_COMPOSING_TEXT));
174 }
175
176 public void sendKeyEvent(KeyEvent event) {
177 dispatchMessage(obtainMessageO(DO_SEND_KEY_EVENT, event));
178 }
179
180 public void clearMetaKeyStates(int states) {
181 dispatchMessage(obtainMessageII(DO_CLEAR_META_KEY_STATES, states, 0));
182 }
183
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800184 public void deleteSurroundingText(int beforeLength, int afterLength) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185 dispatchMessage(obtainMessageII(DO_DELETE_SURROUNDING_TEXT,
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800186 beforeLength, afterLength));
187 }
188
189 public void deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
190 dispatchMessage(obtainMessageII(DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS,
191 beforeLength, afterLength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192 }
193
194 public void beginBatchEdit() {
195 dispatchMessage(obtainMessage(DO_BEGIN_BATCH_EDIT));
196 }
197
198 public void endBatchEdit() {
199 dispatchMessage(obtainMessage(DO_END_BATCH_EDIT));
200 }
201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 public void performPrivateCommand(String action, Bundle data) {
203 dispatchMessage(obtainMessageOO(DO_PERFORM_PRIVATE_COMMAND, action, data));
204 }
satokadb43582011-03-09 10:08:47 +0900205
Yohei Yukawaa277db22014-08-21 18:38:44 -0700206 public void requestUpdateCursorAnchorInfo(int cursorUpdateMode, int seq,
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900207 IInputContextCallback callback) {
Yohei Yukawaa277db22014-08-21 18:38:44 -0700208 dispatchMessage(obtainMessageISC(DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO, cursorUpdateMode,
209 seq, callback));
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900210 }
211
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700212 public void closeConnection() {
213 dispatchMessage(obtainMessage(DO_CLOSE_CONNECTION));
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700214 }
215
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700216 public void commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts,
Yohei Yukawa152944f2016-06-10 19:04:34 -0700217 int seq, IInputContextCallback callback) {
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700218 dispatchMessage(obtainMessageIOOSC(DO_COMMIT_CONTENT, flags, inputContentInfo, opts, seq,
219 callback));
Yohei Yukawa152944f2016-06-10 19:04:34 -0700220 }
221
Yohei Yukawae77386e2018-01-23 10:39:32 -0800222 public void reportLanguageHint(@NonNull LocaleList languageHint) {
223 dispatchMessage(obtainMessageO(DO_REPORT_LANGUAGE_HINT, languageHint));
224 }
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 Yukawace82eb22017-02-12 23:16:47 -0800244 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
245 final int callbackSeq = args.argi6;
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");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800249 callback.setTextAfterCursor(null, callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 return;
251 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800252 callback.setTextAfterCursor(ic.getTextAfterCursor(
253 msg.arg1, msg.arg2), callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254 } catch (RemoteException e) {
255 Log.w(TAG, "Got RemoteException calling setTextAfterCursor", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800256 } finally {
257 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258 }
259 return;
260 }
261 case DO_GET_TEXT_BEFORE_CURSOR: {
262 SomeArgs args = (SomeArgs)msg.obj;
263 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800264 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
265 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700266 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 if (ic == null || !isActive()) {
268 Log.w(TAG, "getTextBeforeCursor on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800269 callback.setTextBeforeCursor(null, callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270 return;
271 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800272 callback.setTextBeforeCursor(ic.getTextBeforeCursor(
273 msg.arg1, msg.arg2), callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 } catch (RemoteException e) {
275 Log.w(TAG, "Got RemoteException calling setTextBeforeCursor", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800276 } finally {
277 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 }
279 return;
280 }
Amith Yamasania90b7f02010-08-25 18:27:20 -0700281 case DO_GET_SELECTED_TEXT: {
282 SomeArgs args = (SomeArgs)msg.obj;
283 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800284 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
285 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700286 InputConnection ic = getInputConnection();
Amith Yamasania90b7f02010-08-25 18:27:20 -0700287 if (ic == null || !isActive()) {
288 Log.w(TAG, "getSelectedText on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800289 callback.setSelectedText(null, callbackSeq);
Amith Yamasania90b7f02010-08-25 18:27:20 -0700290 return;
291 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800292 callback.setSelectedText(ic.getSelectedText(
293 msg.arg1), callbackSeq);
Amith Yamasania90b7f02010-08-25 18:27:20 -0700294 } catch (RemoteException e) {
295 Log.w(TAG, "Got RemoteException calling setSelectedText", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800296 } finally {
297 args.recycle();
Amith Yamasania90b7f02010-08-25 18:27:20 -0700298 }
299 return;
300 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 case DO_GET_CURSOR_CAPS_MODE: {
302 SomeArgs args = (SomeArgs)msg.obj;
303 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800304 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
305 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700306 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800307 if (ic == null || !isActive()) {
308 Log.w(TAG, "getCursorCapsMode on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800309 callback.setCursorCapsMode(0, callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 return;
311 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800312 callback.setCursorCapsMode(ic.getCursorCapsMode(msg.arg1),
313 callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314 } catch (RemoteException e) {
315 Log.w(TAG, "Got RemoteException calling setCursorCapsMode", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800316 } finally {
317 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 }
319 return;
320 }
321 case DO_GET_EXTRACTED_TEXT: {
322 SomeArgs args = (SomeArgs)msg.obj;
323 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800324 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
325 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700326 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 if (ic == null || !isActive()) {
328 Log.w(TAG, "getExtractedText on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800329 callback.setExtractedText(null, callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 return;
331 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800332 callback.setExtractedText(ic.getExtractedText(
333 (ExtractedTextRequest)args.arg1, msg.arg1), callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 } catch (RemoteException e) {
335 Log.w(TAG, "Got RemoteException calling setExtractedText", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800336 } finally {
337 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 }
339 return;
340 }
341 case DO_COMMIT_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700342 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 if (ic == null || !isActive()) {
344 Log.w(TAG, "commitText on inactive InputConnection");
345 return;
346 }
347 ic.commitText((CharSequence)msg.obj, msg.arg1);
Yohei Yukawa159dd472016-01-07 16:52:33 -0800348 onUserAction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 return;
350 }
351 case DO_SET_SELECTION: {
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, "setSelection on inactive InputConnection");
355 return;
356 }
357 ic.setSelection(msg.arg1, msg.arg2);
358 return;
359 }
360 case DO_PERFORM_EDITOR_ACTION: {
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, "performEditorAction on inactive InputConnection");
364 return;
365 }
366 ic.performEditorAction(msg.arg1);
367 return;
368 }
369 case DO_PERFORM_CONTEXT_MENU_ACTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700370 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371 if (ic == null || !isActive()) {
372 Log.w(TAG, "performContextMenuAction on inactive InputConnection");
373 return;
374 }
375 ic.performContextMenuAction(msg.arg1);
376 return;
377 }
378 case DO_COMMIT_COMPLETION: {
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, "commitCompletion on inactive InputConnection");
382 return;
383 }
384 ic.commitCompletion((CompletionInfo)msg.obj);
385 return;
386 }
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800387 case DO_COMMIT_CORRECTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700388 InputConnection ic = getInputConnection();
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800389 if (ic == null || !isActive()) {
390 Log.w(TAG, "commitCorrection on inactive InputConnection");
391 return;
392 }
393 ic.commitCorrection((CorrectionInfo)msg.obj);
394 return;
395 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800396 case DO_SET_COMPOSING_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700397 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 if (ic == null || !isActive()) {
399 Log.w(TAG, "setComposingText on inactive InputConnection");
400 return;
401 }
402 ic.setComposingText((CharSequence)msg.obj, msg.arg1);
Yohei Yukawa159dd472016-01-07 16:52:33 -0800403 onUserAction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800404 return;
405 }
Amith Yamasania90b7f02010-08-25 18:27:20 -0700406 case DO_SET_COMPOSING_REGION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700407 InputConnection ic = getInputConnection();
Amith Yamasania90b7f02010-08-25 18:27:20 -0700408 if (ic == null || !isActive()) {
409 Log.w(TAG, "setComposingRegion on inactive InputConnection");
410 return;
411 }
412 ic.setComposingRegion(msg.arg1, msg.arg2);
413 return;
414 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 case DO_FINISH_COMPOSING_TEXT: {
Yohei Yukawa77e51832017-02-12 20:08:13 -0800416 if (isFinished()) {
417 // In this case, #finishComposingText() is guaranteed to be called already.
418 // There should be no negative impact if we ignore this call silently.
419 if (DEBUG) {
420 Log.w(TAG, "Bug 35301295: Redundant finishComposingText.");
421 }
422 return;
423 }
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700424 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 // Note we do NOT check isActive() here, because this is safe
426 // for an IME to call at any time, and we need to allow it
427 // through to clean up our state after the IME has switched to
428 // another client.
429 if (ic == null) {
430 Log.w(TAG, "finishComposingText on inactive InputConnection");
431 return;
432 }
433 ic.finishComposingText();
434 return;
435 }
436 case DO_SEND_KEY_EVENT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700437 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438 if (ic == null || !isActive()) {
439 Log.w(TAG, "sendKeyEvent on inactive InputConnection");
440 return;
441 }
442 ic.sendKeyEvent((KeyEvent)msg.obj);
Yohei Yukawa159dd472016-01-07 16:52:33 -0800443 onUserAction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800444 return;
445 }
446 case DO_CLEAR_META_KEY_STATES: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700447 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800448 if (ic == null || !isActive()) {
449 Log.w(TAG, "clearMetaKeyStates on inactive InputConnection");
450 return;
451 }
452 ic.clearMetaKeyStates(msg.arg1);
453 return;
454 }
455 case DO_DELETE_SURROUNDING_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700456 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800457 if (ic == null || !isActive()) {
458 Log.w(TAG, "deleteSurroundingText on inactive InputConnection");
459 return;
460 }
461 ic.deleteSurroundingText(msg.arg1, msg.arg2);
462 return;
463 }
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800464 case DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700465 InputConnection ic = getInputConnection();
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800466 if (ic == null || !isActive()) {
467 Log.w(TAG, "deleteSurroundingTextInCodePoints on inactive InputConnection");
468 return;
469 }
470 ic.deleteSurroundingTextInCodePoints(msg.arg1, msg.arg2);
471 return;
472 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 case DO_BEGIN_BATCH_EDIT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700474 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475 if (ic == null || !isActive()) {
476 Log.w(TAG, "beginBatchEdit on inactive InputConnection");
477 return;
478 }
479 ic.beginBatchEdit();
480 return;
481 }
482 case DO_END_BATCH_EDIT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700483 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484 if (ic == null || !isActive()) {
485 Log.w(TAG, "endBatchEdit on inactive InputConnection");
486 return;
487 }
488 ic.endBatchEdit();
489 return;
490 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491 case DO_PERFORM_PRIVATE_COMMAND: {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800492 final SomeArgs args = (SomeArgs) msg.obj;
493 try {
494 final String action = (String) args.arg1;
495 final Bundle data = (Bundle) args.arg2;
496 InputConnection ic = getInputConnection();
497 if (ic == null || !isActive()) {
498 Log.w(TAG, "performPrivateCommand on inactive InputConnection");
499 return;
500 }
501 ic.performPrivateCommand(action, data);
502 } finally {
503 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 }
Yohei Yukawa3dd5fbc2017-02-22 20:49:10 -0800505 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 }
Yohei Yukawaa277db22014-08-21 18:38:44 -0700507 case DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO: {
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900508 SomeArgs args = (SomeArgs)msg.obj;
509 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800510 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
511 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700512 InputConnection ic = getInputConnection();
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900513 if (ic == null || !isActive()) {
514 Log.w(TAG, "requestCursorAnchorInfo on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800515 callback.setRequestUpdateCursorAnchorInfoResult(false, callbackSeq);
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900516 return;
517 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800518 callback.setRequestUpdateCursorAnchorInfoResult(
519 ic.requestCursorUpdates(msg.arg1), callbackSeq);
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900520 } catch (RemoteException e) {
521 Log.w(TAG, "Got RemoteException calling requestCursorAnchorInfo", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800522 } finally {
523 args.recycle();
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900524 }
525 return;
526 }
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700527 case DO_CLOSE_CONNECTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700528 // Note that we do not need to worry about race condition here, because 1) mFinished
529 // is updated only inside this block, and 2) the code here is running on a Handler
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700530 // hence we assume multiple DO_CLOSE_CONNECTION messages will not be handled at the
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700531 // same time.
532 if (isFinished()) {
533 return;
534 }
535 try {
536 InputConnection ic = getInputConnection();
537 // Note we do NOT check isActive() here, because this is safe
538 // for an IME to call at any time, and we need to allow it
539 // through to clean up our state after the IME has switched to
540 // another client.
541 if (ic == null) {
542 return;
543 }
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700544 @MissingMethodFlags
545 final int missingMethods = InputConnectionInspector.getMissingMethodFlags(ic);
546 if ((missingMethods & MissingMethodFlags.CLOSE_CONNECTION) == 0) {
547 ic.closeConnection();
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700548 }
549 } finally {
550 synchronized (mLock) {
551 mInputConnection = null;
552 mFinished = true;
553 }
554 }
555 return;
556 }
Yohei Yukawaadebb522016-06-17 10:10:39 -0700557 case DO_COMMIT_CONTENT: {
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700558 final int flags = msg.arg1;
Yohei Yukawa152944f2016-06-10 19:04:34 -0700559 SomeArgs args = (SomeArgs) msg.obj;
560 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800561 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
562 final int callbackSeq = args.argi6;
Yohei Yukawa152944f2016-06-10 19:04:34 -0700563 InputConnection ic = getInputConnection();
564 if (ic == null || !isActive()) {
Yohei Yukawaadebb522016-06-17 10:10:39 -0700565 Log.w(TAG, "commitContent on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800566 callback.setCommitContentResult(false, callbackSeq);
Yohei Yukawa152944f2016-06-10 19:04:34 -0700567 return;
568 }
569 final InputContentInfo inputContentInfo = (InputContentInfo) args.arg1;
570 if (inputContentInfo == null || !inputContentInfo.validate()) {
Yohei Yukawaadebb522016-06-17 10:10:39 -0700571 Log.w(TAG, "commitContent with invalid inputContentInfo="
Yohei Yukawa152944f2016-06-10 19:04:34 -0700572 + inputContentInfo);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800573 callback.setCommitContentResult(false, callbackSeq);
Yohei Yukawa152944f2016-06-10 19:04:34 -0700574 return;
575 }
Yohei Yukawaf3806f52016-06-30 16:27:46 -0700576 final boolean result =
577 ic.commitContent(inputContentInfo, flags, (Bundle) args.arg2);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800578 callback.setCommitContentResult(result, callbackSeq);
Yohei Yukawa152944f2016-06-10 19:04:34 -0700579 } catch (RemoteException e) {
Yohei Yukawaadebb522016-06-17 10:10:39 -0700580 Log.w(TAG, "Got RemoteException calling commitContent", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800581 } finally {
582 args.recycle();
Yohei Yukawa152944f2016-06-10 19:04:34 -0700583 }
584 return;
585 }
Yohei Yukawae77386e2018-01-23 10:39:32 -0800586 case DO_REPORT_LANGUAGE_HINT: {
587 final LocaleList languageHint = (LocaleList) msg.obj;
588 final InputConnection ic = getInputConnection();
589 if (ic == null || !isActive()) {
590 Log.w(TAG, "reportLanguageHint on inactive InputConnection");
591 return;
592 }
593 ic.reportLanguageHint(languageHint);
594 return;
595 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800596 }
597 Log.w(TAG, "Unhandled message code: " + msg.what);
598 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800599
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 Message obtainMessage(int what) {
601 return mH.obtainMessage(what);
602 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 Message obtainMessageII(int what, int arg1, int arg2) {
605 return mH.obtainMessage(what, arg1, arg2);
606 }
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800608 Message obtainMessageO(int what, Object arg1) {
609 return mH.obtainMessage(what, 0, 0, arg1);
610 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800611
612 Message obtainMessageISC(int what, int arg1, int callbackSeq, IInputContextCallback callback) {
613 final SomeArgs args = SomeArgs.obtain();
614 args.arg6 = callback;
615 args.argi6 = callbackSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800616 return mH.obtainMessage(what, arg1, 0, args);
617 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800618
619 Message obtainMessageIISC(int what, int arg1, int arg2, int callbackSeq,
620 IInputContextCallback callback) {
621 final SomeArgs args = SomeArgs.obtain();
622 args.arg6 = callback;
623 args.argi6 = callbackSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800624 return mH.obtainMessage(what, arg1, arg2, args);
625 }
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900626
Yohei Yukawace82eb22017-02-12 23:16:47 -0800627 Message obtainMessageIOOSC(int what, int arg1, Object objArg1, Object objArg2, int callbackSeq,
Yohei Yukawa152944f2016-06-10 19:04:34 -0700628 IInputContextCallback callback) {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800629 final SomeArgs args = SomeArgs.obtain();
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700630 args.arg1 = objArg1;
631 args.arg2 = objArg2;
Yohei Yukawace82eb22017-02-12 23:16:47 -0800632 args.arg6 = callback;
633 args.argi6 = callbackSeq;
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700634 return mH.obtainMessage(what, arg1, 0, args);
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900635 }
636
Yohei Yukawace82eb22017-02-12 23:16:47 -0800637 Message obtainMessageIOSC(int what, int arg1, Object arg2, int callbackSeq,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800638 IInputContextCallback callback) {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800639 final SomeArgs args = SomeArgs.obtain();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800640 args.arg1 = arg2;
Yohei Yukawace82eb22017-02-12 23:16:47 -0800641 args.arg6 = callback;
642 args.argi6 = callbackSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800643 return mH.obtainMessage(what, arg1, 0, args);
644 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800645
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800646 Message obtainMessageIO(int what, int arg1, Object arg2) {
647 return mH.obtainMessage(what, arg1, 0, arg2);
648 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800649
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800650 Message obtainMessageOO(int what, Object arg1, Object arg2) {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800651 final SomeArgs args = SomeArgs.obtain();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800652 args.arg1 = arg1;
653 args.arg2 = arg2;
654 return mH.obtainMessage(what, 0, 0, args);
655 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800656}