blob: 555263dd3699654c13fa19f495fa4a203f5c7600 [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;
26import android.os.Looper;
27import android.os.Message;
28import android.os.RemoteException;
29import android.util.Log;
30import android.view.KeyEvent;
31import android.view.inputmethod.CompletionInfo;
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -080032import android.view.inputmethod.CorrectionInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import android.view.inputmethod.ExtractedTextRequest;
34import android.view.inputmethod.InputConnection;
Yohei Yukawa9f9afe522016-03-30 12:03:51 -070035import android.view.inputmethod.InputConnectionInspector;
36import android.view.inputmethod.InputConnectionInspector.MissingMethodFlags;
Yohei Yukawa152944f2016-06-10 19:04:34 -070037import android.view.inputmethod.InputContentInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038
Yohei Yukawa159dd472016-01-07 16:52:33 -080039public abstract class IInputConnectionWrapper extends IInputContext.Stub {
Yohei Yukawa77e51832017-02-12 20:08:13 -080040 private static final String TAG = "IInputConnectionWrapper";
41 private static final boolean DEBUG = false;
Amith Yamasania90b7f02010-08-25 18:27:20 -070042
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043 private static final int DO_GET_TEXT_AFTER_CURSOR = 10;
44 private static final int DO_GET_TEXT_BEFORE_CURSOR = 20;
Amith Yamasania90b7f02010-08-25 18:27:20 -070045 private static final int DO_GET_SELECTED_TEXT = 25;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046 private static final int DO_GET_CURSOR_CAPS_MODE = 30;
47 private static final int DO_GET_EXTRACTED_TEXT = 40;
48 private static final int DO_COMMIT_TEXT = 50;
49 private static final int DO_COMMIT_COMPLETION = 55;
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -080050 private static final int DO_COMMIT_CORRECTION = 56;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051 private static final int DO_SET_SELECTION = 57;
52 private static final int DO_PERFORM_EDITOR_ACTION = 58;
53 private static final int DO_PERFORM_CONTEXT_MENU_ACTION = 59;
54 private static final int DO_SET_COMPOSING_TEXT = 60;
Amith Yamasania90b7f02010-08-25 18:27:20 -070055 private static final int DO_SET_COMPOSING_REGION = 63;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056 private static final int DO_FINISH_COMPOSING_TEXT = 65;
57 private static final int DO_SEND_KEY_EVENT = 70;
58 private static final int DO_DELETE_SURROUNDING_TEXT = 80;
Yohei Yukawac89e22a2016-01-13 22:48:14 -080059 private static final int DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS = 81;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060 private static final int DO_BEGIN_BATCH_EDIT = 90;
61 private static final int DO_END_BATCH_EDIT = 95;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062 private static final int DO_PERFORM_PRIVATE_COMMAND = 120;
63 private static final int DO_CLEAR_META_KEY_STATES = 130;
Yohei Yukawaa277db22014-08-21 18:38:44 -070064 private static final int DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO = 140;
Yohei Yukawa9f9afe522016-03-30 12:03:51 -070065 private static final int DO_CLOSE_CONNECTION = 150;
Yohei Yukawaadebb522016-06-17 10:10:39 -070066 private static final int DO_COMMIT_CONTENT = 160;
Amith Yamasania90b7f02010-08-25 18:27:20 -070067
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070068 @GuardedBy("mLock")
69 @Nullable
70 private InputConnection mInputConnection;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071
72 private Looper mMainLooper;
73 private Handler mH;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070074 private Object mLock = new Object();
75 @GuardedBy("mLock")
76 private boolean mFinished = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078 class MyHandler extends Handler {
79 MyHandler(Looper looper) {
80 super(looper);
81 }
82
83 @Override
84 public void handleMessage(Message msg) {
85 executeMessage(msg);
86 }
87 }
88
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070089 public IInputConnectionWrapper(Looper mainLooper, @NonNull InputConnection inputConnection) {
90 mInputConnection = inputConnection;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 mMainLooper = mainLooper;
92 mH = new MyHandler(mMainLooper);
93 }
94
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070095 @Nullable
96 public InputConnection getInputConnection() {
97 synchronized (mLock) {
98 return mInputConnection;
99 }
100 }
101
102 protected boolean isFinished() {
103 synchronized (mLock) {
104 return mFinished;
105 }
106 }
107
Yohei Yukawa159dd472016-01-07 16:52:33 -0800108 abstract protected boolean isActive();
109
110 /**
111 * Called when the user took some actions that should be taken into consideration to update the
112 * LRU list for input method rotation.
113 */
114 abstract protected void onUserAction();
115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 public void getTextAfterCursor(int length, int flags, int seq, IInputContextCallback callback) {
117 dispatchMessage(obtainMessageIISC(DO_GET_TEXT_AFTER_CURSOR, length, flags, seq, callback));
118 }
119
120 public void getTextBeforeCursor(int length, int flags, int seq, IInputContextCallback callback) {
121 dispatchMessage(obtainMessageIISC(DO_GET_TEXT_BEFORE_CURSOR, length, flags, seq, callback));
122 }
123
Amith Yamasania90b7f02010-08-25 18:27:20 -0700124 public void getSelectedText(int flags, int seq, IInputContextCallback callback) {
125 dispatchMessage(obtainMessageISC(DO_GET_SELECTED_TEXT, flags, seq, callback));
126 }
127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128 public void getCursorCapsMode(int reqModes, int seq, IInputContextCallback callback) {
129 dispatchMessage(obtainMessageISC(DO_GET_CURSOR_CAPS_MODE, reqModes, seq, callback));
130 }
131
132 public void getExtractedText(ExtractedTextRequest request,
133 int flags, int seq, IInputContextCallback callback) {
134 dispatchMessage(obtainMessageIOSC(DO_GET_EXTRACTED_TEXT, flags,
135 request, seq, callback));
136 }
137
138 public void commitText(CharSequence text, int newCursorPosition) {
139 dispatchMessage(obtainMessageIO(DO_COMMIT_TEXT, newCursorPosition, text));
140 }
141
142 public void commitCompletion(CompletionInfo text) {
143 dispatchMessage(obtainMessageO(DO_COMMIT_COMPLETION, text));
144 }
145
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800146 public void commitCorrection(CorrectionInfo info) {
147 dispatchMessage(obtainMessageO(DO_COMMIT_CORRECTION, info));
148 }
149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 public void setSelection(int start, int end) {
151 dispatchMessage(obtainMessageII(DO_SET_SELECTION, start, end));
152 }
153
154 public void performEditorAction(int id) {
155 dispatchMessage(obtainMessageII(DO_PERFORM_EDITOR_ACTION, id, 0));
156 }
157
158 public void performContextMenuAction(int id) {
159 dispatchMessage(obtainMessageII(DO_PERFORM_CONTEXT_MENU_ACTION, id, 0));
160 }
161
Amith Yamasania90b7f02010-08-25 18:27:20 -0700162 public void setComposingRegion(int start, int end) {
163 dispatchMessage(obtainMessageII(DO_SET_COMPOSING_REGION, start, end));
164 }
165
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 public void setComposingText(CharSequence text, int newCursorPosition) {
167 dispatchMessage(obtainMessageIO(DO_SET_COMPOSING_TEXT, newCursorPosition, text));
168 }
169
170 public void finishComposingText() {
171 dispatchMessage(obtainMessage(DO_FINISH_COMPOSING_TEXT));
172 }
173
174 public void sendKeyEvent(KeyEvent event) {
175 dispatchMessage(obtainMessageO(DO_SEND_KEY_EVENT, event));
176 }
177
178 public void clearMetaKeyStates(int states) {
179 dispatchMessage(obtainMessageII(DO_CLEAR_META_KEY_STATES, states, 0));
180 }
181
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800182 public void deleteSurroundingText(int beforeLength, int afterLength) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 dispatchMessage(obtainMessageII(DO_DELETE_SURROUNDING_TEXT,
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800184 beforeLength, afterLength));
185 }
186
187 public void deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
188 dispatchMessage(obtainMessageII(DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS,
189 beforeLength, afterLength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 }
191
192 public void beginBatchEdit() {
193 dispatchMessage(obtainMessage(DO_BEGIN_BATCH_EDIT));
194 }
195
196 public void endBatchEdit() {
197 dispatchMessage(obtainMessage(DO_END_BATCH_EDIT));
198 }
199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200 public void performPrivateCommand(String action, Bundle data) {
201 dispatchMessage(obtainMessageOO(DO_PERFORM_PRIVATE_COMMAND, action, data));
202 }
satokadb43582011-03-09 10:08:47 +0900203
Yohei Yukawaa277db22014-08-21 18:38:44 -0700204 public void requestUpdateCursorAnchorInfo(int cursorUpdateMode, int seq,
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900205 IInputContextCallback callback) {
Yohei Yukawaa277db22014-08-21 18:38:44 -0700206 dispatchMessage(obtainMessageISC(DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO, cursorUpdateMode,
207 seq, callback));
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900208 }
209
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700210 public void closeConnection() {
211 dispatchMessage(obtainMessage(DO_CLOSE_CONNECTION));
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700212 }
213
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700214 public void commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts,
Yohei Yukawa152944f2016-06-10 19:04:34 -0700215 int seq, IInputContextCallback callback) {
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700216 dispatchMessage(obtainMessageIOOSC(DO_COMMIT_CONTENT, flags, inputContentInfo, opts, seq,
217 callback));
Yohei Yukawa152944f2016-06-10 19:04:34 -0700218 }
219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 void dispatchMessage(Message msg) {
221 // If we are calling this from the main thread, then we can call
222 // right through. Otherwise, we need to send the message to the
223 // main thread.
224 if (Looper.myLooper() == mMainLooper) {
225 executeMessage(msg);
226 msg.recycle();
227 return;
228 }
229
230 mH.sendMessage(msg);
231 }
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233 void executeMessage(Message msg) {
234 switch (msg.what) {
235 case DO_GET_TEXT_AFTER_CURSOR: {
236 SomeArgs args = (SomeArgs)msg.obj;
237 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800238 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
239 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700240 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 if (ic == null || !isActive()) {
242 Log.w(TAG, "getTextAfterCursor on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800243 callback.setTextAfterCursor(null, callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 return;
245 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800246 callback.setTextAfterCursor(ic.getTextAfterCursor(
247 msg.arg1, msg.arg2), callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 } catch (RemoteException e) {
249 Log.w(TAG, "Got RemoteException calling setTextAfterCursor", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800250 } finally {
251 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252 }
253 return;
254 }
255 case DO_GET_TEXT_BEFORE_CURSOR: {
256 SomeArgs args = (SomeArgs)msg.obj;
257 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800258 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
259 final int callbackSeq = args.argi6;
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");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800263 callback.setTextBeforeCursor(null, callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 return;
265 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800266 callback.setTextBeforeCursor(ic.getTextBeforeCursor(
267 msg.arg1, msg.arg2), callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 } catch (RemoteException e) {
269 Log.w(TAG, "Got RemoteException calling setTextBeforeCursor", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800270 } finally {
271 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272 }
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 Yukawace82eb22017-02-12 23:16:47 -0800278 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
279 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700280 InputConnection ic = getInputConnection();
Amith Yamasania90b7f02010-08-25 18:27:20 -0700281 if (ic == null || !isActive()) {
282 Log.w(TAG, "getSelectedText on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800283 callback.setSelectedText(null, callbackSeq);
Amith Yamasania90b7f02010-08-25 18:27:20 -0700284 return;
285 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800286 callback.setSelectedText(ic.getSelectedText(
287 msg.arg1), callbackSeq);
Amith Yamasania90b7f02010-08-25 18:27:20 -0700288 } catch (RemoteException e) {
289 Log.w(TAG, "Got RemoteException calling setSelectedText", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800290 } finally {
291 args.recycle();
Amith Yamasania90b7f02010-08-25 18:27:20 -0700292 }
293 return;
294 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800295 case DO_GET_CURSOR_CAPS_MODE: {
296 SomeArgs args = (SomeArgs)msg.obj;
297 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800298 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
299 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700300 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 if (ic == null || !isActive()) {
302 Log.w(TAG, "getCursorCapsMode on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800303 callback.setCursorCapsMode(0, callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 return;
305 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800306 callback.setCursorCapsMode(ic.getCursorCapsMode(msg.arg1),
307 callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 } catch (RemoteException e) {
309 Log.w(TAG, "Got RemoteException calling setCursorCapsMode", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800310 } finally {
311 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312 }
313 return;
314 }
315 case DO_GET_EXTRACTED_TEXT: {
316 SomeArgs args = (SomeArgs)msg.obj;
317 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800318 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
319 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700320 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321 if (ic == null || !isActive()) {
322 Log.w(TAG, "getExtractedText on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800323 callback.setExtractedText(null, callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324 return;
325 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800326 callback.setExtractedText(ic.getExtractedText(
327 (ExtractedTextRequest)args.arg1, msg.arg1), callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 } catch (RemoteException e) {
329 Log.w(TAG, "Got RemoteException calling setExtractedText", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800330 } finally {
331 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332 }
333 return;
334 }
335 case DO_COMMIT_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700336 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 if (ic == null || !isActive()) {
338 Log.w(TAG, "commitText on inactive InputConnection");
339 return;
340 }
341 ic.commitText((CharSequence)msg.obj, msg.arg1);
Yohei Yukawa159dd472016-01-07 16:52:33 -0800342 onUserAction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 return;
344 }
345 case DO_SET_SELECTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700346 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 if (ic == null || !isActive()) {
348 Log.w(TAG, "setSelection on inactive InputConnection");
349 return;
350 }
351 ic.setSelection(msg.arg1, msg.arg2);
352 return;
353 }
354 case DO_PERFORM_EDITOR_ACTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700355 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800356 if (ic == null || !isActive()) {
357 Log.w(TAG, "performEditorAction on inactive InputConnection");
358 return;
359 }
360 ic.performEditorAction(msg.arg1);
361 return;
362 }
363 case DO_PERFORM_CONTEXT_MENU_ACTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700364 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365 if (ic == null || !isActive()) {
366 Log.w(TAG, "performContextMenuAction on inactive InputConnection");
367 return;
368 }
369 ic.performContextMenuAction(msg.arg1);
370 return;
371 }
372 case DO_COMMIT_COMPLETION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700373 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800374 if (ic == null || !isActive()) {
375 Log.w(TAG, "commitCompletion on inactive InputConnection");
376 return;
377 }
378 ic.commitCompletion((CompletionInfo)msg.obj);
379 return;
380 }
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800381 case DO_COMMIT_CORRECTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700382 InputConnection ic = getInputConnection();
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800383 if (ic == null || !isActive()) {
384 Log.w(TAG, "commitCorrection on inactive InputConnection");
385 return;
386 }
387 ic.commitCorrection((CorrectionInfo)msg.obj);
388 return;
389 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 case DO_SET_COMPOSING_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700391 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 if (ic == null || !isActive()) {
393 Log.w(TAG, "setComposingText on inactive InputConnection");
394 return;
395 }
396 ic.setComposingText((CharSequence)msg.obj, msg.arg1);
Yohei Yukawa159dd472016-01-07 16:52:33 -0800397 onUserAction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 return;
399 }
Amith Yamasania90b7f02010-08-25 18:27:20 -0700400 case DO_SET_COMPOSING_REGION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700401 InputConnection ic = getInputConnection();
Amith Yamasania90b7f02010-08-25 18:27:20 -0700402 if (ic == null || !isActive()) {
403 Log.w(TAG, "setComposingRegion on inactive InputConnection");
404 return;
405 }
406 ic.setComposingRegion(msg.arg1, msg.arg2);
407 return;
408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 case DO_FINISH_COMPOSING_TEXT: {
Yohei Yukawa77e51832017-02-12 20:08:13 -0800410 if (isFinished()) {
411 // In this case, #finishComposingText() is guaranteed to be called already.
412 // There should be no negative impact if we ignore this call silently.
413 if (DEBUG) {
414 Log.w(TAG, "Bug 35301295: Redundant finishComposingText.");
415 }
416 return;
417 }
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700418 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 // Note we do NOT check isActive() here, because this is safe
420 // for an IME to call at any time, and we need to allow it
421 // through to clean up our state after the IME has switched to
422 // another client.
423 if (ic == null) {
424 Log.w(TAG, "finishComposingText on inactive InputConnection");
425 return;
426 }
427 ic.finishComposingText();
428 return;
429 }
430 case DO_SEND_KEY_EVENT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700431 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800432 if (ic == null || !isActive()) {
433 Log.w(TAG, "sendKeyEvent on inactive InputConnection");
434 return;
435 }
436 ic.sendKeyEvent((KeyEvent)msg.obj);
Yohei Yukawa159dd472016-01-07 16:52:33 -0800437 onUserAction();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438 return;
439 }
440 case DO_CLEAR_META_KEY_STATES: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700441 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442 if (ic == null || !isActive()) {
443 Log.w(TAG, "clearMetaKeyStates on inactive InputConnection");
444 return;
445 }
446 ic.clearMetaKeyStates(msg.arg1);
447 return;
448 }
449 case DO_DELETE_SURROUNDING_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700450 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 if (ic == null || !isActive()) {
452 Log.w(TAG, "deleteSurroundingText on inactive InputConnection");
453 return;
454 }
455 ic.deleteSurroundingText(msg.arg1, msg.arg2);
456 return;
457 }
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800458 case DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700459 InputConnection ic = getInputConnection();
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800460 if (ic == null || !isActive()) {
461 Log.w(TAG, "deleteSurroundingTextInCodePoints on inactive InputConnection");
462 return;
463 }
464 ic.deleteSurroundingTextInCodePoints(msg.arg1, msg.arg2);
465 return;
466 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467 case DO_BEGIN_BATCH_EDIT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700468 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469 if (ic == null || !isActive()) {
470 Log.w(TAG, "beginBatchEdit on inactive InputConnection");
471 return;
472 }
473 ic.beginBatchEdit();
474 return;
475 }
476 case DO_END_BATCH_EDIT: {
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, "endBatchEdit on inactive InputConnection");
480 return;
481 }
482 ic.endBatchEdit();
483 return;
484 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 case DO_PERFORM_PRIVATE_COMMAND: {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800486 final SomeArgs args = (SomeArgs) msg.obj;
487 try {
488 final String action = (String) args.arg1;
489 final Bundle data = (Bundle) args.arg2;
490 InputConnection ic = getInputConnection();
491 if (ic == null || !isActive()) {
492 Log.w(TAG, "performPrivateCommand on inactive InputConnection");
493 return;
494 }
495 ic.performPrivateCommand(action, data);
496 } finally {
497 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800499 }
Yohei Yukawaa277db22014-08-21 18:38:44 -0700500 case DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO: {
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900501 SomeArgs args = (SomeArgs)msg.obj;
502 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800503 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
504 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700505 InputConnection ic = getInputConnection();
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900506 if (ic == null || !isActive()) {
507 Log.w(TAG, "requestCursorAnchorInfo on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800508 callback.setRequestUpdateCursorAnchorInfoResult(false, callbackSeq);
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900509 return;
510 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800511 callback.setRequestUpdateCursorAnchorInfoResult(
512 ic.requestCursorUpdates(msg.arg1), callbackSeq);
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900513 } catch (RemoteException e) {
514 Log.w(TAG, "Got RemoteException calling requestCursorAnchorInfo", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800515 } finally {
516 args.recycle();
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900517 }
518 return;
519 }
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700520 case DO_CLOSE_CONNECTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700521 // Note that we do not need to worry about race condition here, because 1) mFinished
522 // is updated only inside this block, and 2) the code here is running on a Handler
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700523 // hence we assume multiple DO_CLOSE_CONNECTION messages will not be handled at the
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700524 // same time.
525 if (isFinished()) {
526 return;
527 }
528 try {
529 InputConnection ic = getInputConnection();
530 // Note we do NOT check isActive() here, because this is safe
531 // for an IME to call at any time, and we need to allow it
532 // through to clean up our state after the IME has switched to
533 // another client.
534 if (ic == null) {
535 return;
536 }
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700537 @MissingMethodFlags
538 final int missingMethods = InputConnectionInspector.getMissingMethodFlags(ic);
539 if ((missingMethods & MissingMethodFlags.CLOSE_CONNECTION) == 0) {
540 ic.closeConnection();
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700541 }
542 } finally {
543 synchronized (mLock) {
544 mInputConnection = null;
545 mFinished = true;
546 }
547 }
548 return;
549 }
Yohei Yukawaadebb522016-06-17 10:10:39 -0700550 case DO_COMMIT_CONTENT: {
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700551 final int flags = msg.arg1;
Yohei Yukawa152944f2016-06-10 19:04:34 -0700552 SomeArgs args = (SomeArgs) msg.obj;
553 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800554 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
555 final int callbackSeq = args.argi6;
Yohei Yukawa152944f2016-06-10 19:04:34 -0700556 InputConnection ic = getInputConnection();
557 if (ic == null || !isActive()) {
Yohei Yukawaadebb522016-06-17 10:10:39 -0700558 Log.w(TAG, "commitContent on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800559 callback.setCommitContentResult(false, callbackSeq);
Yohei Yukawa152944f2016-06-10 19:04:34 -0700560 return;
561 }
562 final InputContentInfo inputContentInfo = (InputContentInfo) args.arg1;
563 if (inputContentInfo == null || !inputContentInfo.validate()) {
Yohei Yukawaadebb522016-06-17 10:10:39 -0700564 Log.w(TAG, "commitContent with invalid inputContentInfo="
Yohei Yukawa152944f2016-06-10 19:04:34 -0700565 + inputContentInfo);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800566 callback.setCommitContentResult(false, callbackSeq);
Yohei Yukawa152944f2016-06-10 19:04:34 -0700567 return;
568 }
Yohei Yukawaf3806f52016-06-30 16:27:46 -0700569 final boolean result =
570 ic.commitContent(inputContentInfo, flags, (Bundle) args.arg2);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800571 callback.setCommitContentResult(result, callbackSeq);
Yohei Yukawa152944f2016-06-10 19:04:34 -0700572 } catch (RemoteException e) {
Yohei Yukawaadebb522016-06-17 10:10:39 -0700573 Log.w(TAG, "Got RemoteException calling commitContent", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800574 } finally {
575 args.recycle();
Yohei Yukawa152944f2016-06-10 19:04:34 -0700576 }
577 return;
578 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 }
580 Log.w(TAG, "Unhandled message code: " + msg.what);
581 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800582
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583 Message obtainMessage(int what) {
584 return mH.obtainMessage(what);
585 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 Message obtainMessageII(int what, int arg1, int arg2) {
588 return mH.obtainMessage(what, arg1, arg2);
589 }
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800590
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800591 Message obtainMessageO(int what, Object arg1) {
592 return mH.obtainMessage(what, 0, 0, arg1);
593 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800594
595 Message obtainMessageISC(int what, int arg1, int callbackSeq, IInputContextCallback callback) {
596 final SomeArgs args = SomeArgs.obtain();
597 args.arg6 = callback;
598 args.argi6 = callbackSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599 return mH.obtainMessage(what, arg1, 0, args);
600 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800601
602 Message obtainMessageIISC(int what, int arg1, int arg2, int callbackSeq,
603 IInputContextCallback callback) {
604 final SomeArgs args = SomeArgs.obtain();
605 args.arg6 = callback;
606 args.argi6 = callbackSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607 return mH.obtainMessage(what, arg1, arg2, args);
608 }
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900609
Yohei Yukawace82eb22017-02-12 23:16:47 -0800610 Message obtainMessageIOOSC(int what, int arg1, Object objArg1, Object objArg2, int callbackSeq,
Yohei Yukawa152944f2016-06-10 19:04:34 -0700611 IInputContextCallback callback) {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800612 final SomeArgs args = SomeArgs.obtain();
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700613 args.arg1 = objArg1;
614 args.arg2 = objArg2;
Yohei Yukawace82eb22017-02-12 23:16:47 -0800615 args.arg6 = callback;
616 args.argi6 = callbackSeq;
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700617 return mH.obtainMessage(what, arg1, 0, args);
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900618 }
619
Yohei Yukawace82eb22017-02-12 23:16:47 -0800620 Message obtainMessageIOSC(int what, int arg1, Object arg2, int callbackSeq,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800621 IInputContextCallback callback) {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800622 final SomeArgs args = SomeArgs.obtain();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800623 args.arg1 = arg2;
Yohei Yukawace82eb22017-02-12 23:16:47 -0800624 args.arg6 = callback;
625 args.argi6 = callbackSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626 return mH.obtainMessage(what, arg1, 0, args);
627 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 Message obtainMessageIO(int what, int arg1, Object arg2) {
630 return mH.obtainMessage(what, arg1, 0, arg2);
631 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800632
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800633 Message obtainMessageOO(int what, Object arg1, Object arg2) {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800634 final SomeArgs args = SomeArgs.obtain();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635 args.arg1 = arg1;
636 args.arg2 = arg2;
637 return mH.obtainMessage(what, 0, 0, args);
638 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800639}