blob: ececba13c76021e1316fb7ea1e4d4289c516e0ee [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 android.annotation.NonNull;
20import android.annotation.Nullable;
Mathew Inwoodaf972c82018-08-20 14:13:20 +010021import android.annotation.UnsupportedAppUsage;
Mathew Inwood8c854f82018-09-14 12:35:36 +010022import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import android.os.Bundle;
24import android.os.Handler;
25import android.os.Looper;
26import android.os.Message;
27import android.os.RemoteException;
28import android.util.Log;
29import android.view.KeyEvent;
30import android.view.inputmethod.CompletionInfo;
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -080031import android.view.inputmethod.CorrectionInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.view.inputmethod.ExtractedTextRequest;
33import android.view.inputmethod.InputConnection;
Yohei Yukawa9f9afe522016-03-30 12:03:51 -070034import android.view.inputmethod.InputConnectionInspector;
35import android.view.inputmethod.InputConnectionInspector.MissingMethodFlags;
Yohei Yukawa152944f2016-06-10 19:04:34 -070036import android.view.inputmethod.InputContentInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037
Yohei Yukawa5c1989a2018-09-06 10:52:45 -070038import com.android.internal.annotations.GuardedBy;
39import com.android.internal.os.SomeArgs;
40
Yohei Yukawa159dd472016-01-07 16:52:33 -080041public abstract class IInputConnectionWrapper extends IInputContext.Stub {
Yohei Yukawa77e51832017-02-12 20:08:13 -080042 private static final String TAG = "IInputConnectionWrapper";
43 private static final boolean DEBUG = false;
Amith Yamasania90b7f02010-08-25 18:27:20 -070044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045 private static final int DO_GET_TEXT_AFTER_CURSOR = 10;
46 private static final int DO_GET_TEXT_BEFORE_CURSOR = 20;
Amith Yamasania90b7f02010-08-25 18:27:20 -070047 private static final int DO_GET_SELECTED_TEXT = 25;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048 private static final int DO_GET_CURSOR_CAPS_MODE = 30;
49 private static final int DO_GET_EXTRACTED_TEXT = 40;
50 private static final int DO_COMMIT_TEXT = 50;
51 private static final int DO_COMMIT_COMPLETION = 55;
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -080052 private static final int DO_COMMIT_CORRECTION = 56;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053 private static final int DO_SET_SELECTION = 57;
54 private static final int DO_PERFORM_EDITOR_ACTION = 58;
55 private static final int DO_PERFORM_CONTEXT_MENU_ACTION = 59;
56 private static final int DO_SET_COMPOSING_TEXT = 60;
Amith Yamasania90b7f02010-08-25 18:27:20 -070057 private static final int DO_SET_COMPOSING_REGION = 63;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058 private static final int DO_FINISH_COMPOSING_TEXT = 65;
59 private static final int DO_SEND_KEY_EVENT = 70;
60 private static final int DO_DELETE_SURROUNDING_TEXT = 80;
Yohei Yukawac89e22a2016-01-13 22:48:14 -080061 private static final int DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS = 81;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062 private static final int DO_BEGIN_BATCH_EDIT = 90;
63 private static final int DO_END_BATCH_EDIT = 95;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064 private static final int DO_PERFORM_PRIVATE_COMMAND = 120;
65 private static final int DO_CLEAR_META_KEY_STATES = 130;
Yohei Yukawaa277db22014-08-21 18:38:44 -070066 private static final int DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO = 140;
Yohei Yukawa9f9afe522016-03-30 12:03:51 -070067 private static final int DO_CLOSE_CONNECTION = 150;
Yohei Yukawaadebb522016-06-17 10:10:39 -070068 private static final int DO_COMMIT_CONTENT = 160;
Amith Yamasania90b7f02010-08-25 18:27:20 -070069
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070070 @GuardedBy("mLock")
71 @Nullable
Mathew Inwood8c854f82018-09-14 12:35:36 +010072 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070073 private InputConnection mInputConnection;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074
75 private Looper mMainLooper;
76 private Handler mH;
Mathew Inwoodaf972c82018-08-20 14:13:20 +010077 @UnsupportedAppUsage
Yohei Yukawaaaa38c92016-03-27 23:46:04 -070078 private Object mLock = new Object();
79 @GuardedBy("mLock")
80 private boolean mFinished = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114 public void getTextAfterCursor(int length, int flags, int seq, IInputContextCallback callback) {
115 dispatchMessage(obtainMessageIISC(DO_GET_TEXT_AFTER_CURSOR, length, flags, seq, callback));
116 }
117
118 public void getTextBeforeCursor(int length, int flags, int seq, IInputContextCallback callback) {
119 dispatchMessage(obtainMessageIISC(DO_GET_TEXT_BEFORE_CURSOR, length, flags, seq, callback));
120 }
121
Amith Yamasania90b7f02010-08-25 18:27:20 -0700122 public void getSelectedText(int flags, int seq, IInputContextCallback callback) {
123 dispatchMessage(obtainMessageISC(DO_GET_SELECTED_TEXT, flags, seq, callback));
124 }
125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126 public void getCursorCapsMode(int reqModes, int seq, IInputContextCallback callback) {
127 dispatchMessage(obtainMessageISC(DO_GET_CURSOR_CAPS_MODE, reqModes, seq, callback));
128 }
129
130 public void getExtractedText(ExtractedTextRequest request,
131 int flags, int seq, IInputContextCallback callback) {
132 dispatchMessage(obtainMessageIOSC(DO_GET_EXTRACTED_TEXT, flags,
133 request, seq, callback));
134 }
135
136 public void commitText(CharSequence text, int newCursorPosition) {
137 dispatchMessage(obtainMessageIO(DO_COMMIT_TEXT, newCursorPosition, text));
138 }
139
140 public void commitCompletion(CompletionInfo text) {
141 dispatchMessage(obtainMessageO(DO_COMMIT_COMPLETION, text));
142 }
143
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800144 public void commitCorrection(CorrectionInfo info) {
145 dispatchMessage(obtainMessageO(DO_COMMIT_CORRECTION, info));
146 }
147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 public void setSelection(int start, int end) {
149 dispatchMessage(obtainMessageII(DO_SET_SELECTION, start, end));
150 }
151
152 public void performEditorAction(int id) {
153 dispatchMessage(obtainMessageII(DO_PERFORM_EDITOR_ACTION, id, 0));
154 }
155
156 public void performContextMenuAction(int id) {
157 dispatchMessage(obtainMessageII(DO_PERFORM_CONTEXT_MENU_ACTION, id, 0));
158 }
159
Amith Yamasania90b7f02010-08-25 18:27:20 -0700160 public void setComposingRegion(int start, int end) {
161 dispatchMessage(obtainMessageII(DO_SET_COMPOSING_REGION, start, end));
162 }
163
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 public void setComposingText(CharSequence text, int newCursorPosition) {
165 dispatchMessage(obtainMessageIO(DO_SET_COMPOSING_TEXT, newCursorPosition, text));
166 }
167
168 public void finishComposingText() {
169 dispatchMessage(obtainMessage(DO_FINISH_COMPOSING_TEXT));
170 }
171
172 public void sendKeyEvent(KeyEvent event) {
173 dispatchMessage(obtainMessageO(DO_SEND_KEY_EVENT, event));
174 }
175
176 public void clearMetaKeyStates(int states) {
177 dispatchMessage(obtainMessageII(DO_CLEAR_META_KEY_STATES, states, 0));
178 }
179
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800180 public void deleteSurroundingText(int beforeLength, int afterLength) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 dispatchMessage(obtainMessageII(DO_DELETE_SURROUNDING_TEXT,
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800182 beforeLength, afterLength));
183 }
184
185 public void deleteSurroundingTextInCodePoints(int beforeLength, int afterLength) {
186 dispatchMessage(obtainMessageII(DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS,
187 beforeLength, afterLength));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188 }
189
190 public void beginBatchEdit() {
191 dispatchMessage(obtainMessage(DO_BEGIN_BATCH_EDIT));
192 }
193
194 public void endBatchEdit() {
195 dispatchMessage(obtainMessage(DO_END_BATCH_EDIT));
196 }
197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198 public void performPrivateCommand(String action, Bundle data) {
199 dispatchMessage(obtainMessageOO(DO_PERFORM_PRIVATE_COMMAND, action, data));
200 }
satokadb43582011-03-09 10:08:47 +0900201
Yohei Yukawaa277db22014-08-21 18:38:44 -0700202 public void requestUpdateCursorAnchorInfo(int cursorUpdateMode, int seq,
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900203 IInputContextCallback callback) {
Yohei Yukawaa277db22014-08-21 18:38:44 -0700204 dispatchMessage(obtainMessageISC(DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO, cursorUpdateMode,
205 seq, callback));
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900206 }
207
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700208 public void closeConnection() {
209 dispatchMessage(obtainMessage(DO_CLOSE_CONNECTION));
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700210 }
211
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700212 public void commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts,
Yohei Yukawa152944f2016-06-10 19:04:34 -0700213 int seq, IInputContextCallback callback) {
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700214 dispatchMessage(obtainMessageIOOSC(DO_COMMIT_CONTENT, flags, inputContentInfo, opts, seq,
215 callback));
Yohei Yukawa152944f2016-06-10 19:04:34 -0700216 }
217
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 void dispatchMessage(Message msg) {
219 // If we are calling this from the main thread, then we can call
220 // right through. Otherwise, we need to send the message to the
221 // main thread.
222 if (Looper.myLooper() == mMainLooper) {
223 executeMessage(msg);
224 msg.recycle();
225 return;
226 }
227
228 mH.sendMessage(msg);
229 }
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700230
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 void executeMessage(Message msg) {
232 switch (msg.what) {
233 case DO_GET_TEXT_AFTER_CURSOR: {
234 SomeArgs args = (SomeArgs)msg.obj;
235 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800236 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
237 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700238 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 if (ic == null || !isActive()) {
240 Log.w(TAG, "getTextAfterCursor on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800241 callback.setTextAfterCursor(null, callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 return;
243 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800244 callback.setTextAfterCursor(ic.getTextAfterCursor(
245 msg.arg1, msg.arg2), callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 } catch (RemoteException e) {
247 Log.w(TAG, "Got RemoteException calling setTextAfterCursor", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800248 } finally {
249 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250 }
251 return;
252 }
253 case DO_GET_TEXT_BEFORE_CURSOR: {
254 SomeArgs args = (SomeArgs)msg.obj;
255 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800256 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
257 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700258 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 if (ic == null || !isActive()) {
260 Log.w(TAG, "getTextBeforeCursor on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800261 callback.setTextBeforeCursor(null, callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800262 return;
263 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800264 callback.setTextBeforeCursor(ic.getTextBeforeCursor(
265 msg.arg1, msg.arg2), callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 } catch (RemoteException e) {
267 Log.w(TAG, "Got RemoteException calling setTextBeforeCursor", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800268 } finally {
269 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270 }
271 return;
272 }
Amith Yamasania90b7f02010-08-25 18:27:20 -0700273 case DO_GET_SELECTED_TEXT: {
274 SomeArgs args = (SomeArgs)msg.obj;
275 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800276 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
277 final int callbackSeq = args.argi6;
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");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800281 callback.setSelectedText(null, callbackSeq);
Amith Yamasania90b7f02010-08-25 18:27:20 -0700282 return;
283 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800284 callback.setSelectedText(ic.getSelectedText(
285 msg.arg1), callbackSeq);
Amith Yamasania90b7f02010-08-25 18:27:20 -0700286 } catch (RemoteException e) {
287 Log.w(TAG, "Got RemoteException calling setSelectedText", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800288 } finally {
289 args.recycle();
Amith Yamasania90b7f02010-08-25 18:27:20 -0700290 }
291 return;
292 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293 case DO_GET_CURSOR_CAPS_MODE: {
294 SomeArgs args = (SomeArgs)msg.obj;
295 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800296 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
297 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700298 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 if (ic == null || !isActive()) {
300 Log.w(TAG, "getCursorCapsMode on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800301 callback.setCursorCapsMode(0, callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800302 return;
303 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800304 callback.setCursorCapsMode(ic.getCursorCapsMode(msg.arg1),
305 callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306 } catch (RemoteException e) {
307 Log.w(TAG, "Got RemoteException calling setCursorCapsMode", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800308 } finally {
309 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 }
311 return;
312 }
313 case DO_GET_EXTRACTED_TEXT: {
314 SomeArgs args = (SomeArgs)msg.obj;
315 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800316 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
317 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700318 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 if (ic == null || !isActive()) {
320 Log.w(TAG, "getExtractedText on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800321 callback.setExtractedText(null, callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 return;
323 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800324 callback.setExtractedText(ic.getExtractedText(
325 (ExtractedTextRequest)args.arg1, msg.arg1), callbackSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326 } catch (RemoteException e) {
327 Log.w(TAG, "Got RemoteException calling setExtractedText", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800328 } finally {
329 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 }
331 return;
332 }
333 case DO_COMMIT_TEXT: {
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, "commitText on inactive InputConnection");
337 return;
338 }
339 ic.commitText((CharSequence)msg.obj, msg.arg1);
340 return;
341 }
342 case DO_SET_SELECTION: {
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, "setSelection on inactive InputConnection");
346 return;
347 }
348 ic.setSelection(msg.arg1, msg.arg2);
349 return;
350 }
351 case DO_PERFORM_EDITOR_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, "performEditorAction on inactive InputConnection");
355 return;
356 }
357 ic.performEditorAction(msg.arg1);
358 return;
359 }
360 case DO_PERFORM_CONTEXT_MENU_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, "performContextMenuAction on inactive InputConnection");
364 return;
365 }
366 ic.performContextMenuAction(msg.arg1);
367 return;
368 }
369 case DO_COMMIT_COMPLETION: {
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, "commitCompletion on inactive InputConnection");
373 return;
374 }
375 ic.commitCompletion((CompletionInfo)msg.obj);
376 return;
377 }
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800378 case DO_COMMIT_CORRECTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700379 InputConnection ic = getInputConnection();
Gilles Debunnecf9cf2f2010-12-08 17:43:58 -0800380 if (ic == null || !isActive()) {
381 Log.w(TAG, "commitCorrection on inactive InputConnection");
382 return;
383 }
384 ic.commitCorrection((CorrectionInfo)msg.obj);
385 return;
386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 case DO_SET_COMPOSING_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700388 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 if (ic == null || !isActive()) {
390 Log.w(TAG, "setComposingText on inactive InputConnection");
391 return;
392 }
393 ic.setComposingText((CharSequence)msg.obj, msg.arg1);
394 return;
395 }
Amith Yamasania90b7f02010-08-25 18:27:20 -0700396 case DO_SET_COMPOSING_REGION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700397 InputConnection ic = getInputConnection();
Amith Yamasania90b7f02010-08-25 18:27:20 -0700398 if (ic == null || !isActive()) {
399 Log.w(TAG, "setComposingRegion on inactive InputConnection");
400 return;
401 }
402 ic.setComposingRegion(msg.arg1, msg.arg2);
403 return;
404 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 case DO_FINISH_COMPOSING_TEXT: {
Yohei Yukawa77e51832017-02-12 20:08:13 -0800406 if (isFinished()) {
407 // In this case, #finishComposingText() is guaranteed to be called already.
408 // There should be no negative impact if we ignore this call silently.
409 if (DEBUG) {
410 Log.w(TAG, "Bug 35301295: Redundant finishComposingText.");
411 }
412 return;
413 }
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700414 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800415 // Note we do NOT check isActive() here, because this is safe
416 // for an IME to call at any time, and we need to allow it
417 // through to clean up our state after the IME has switched to
418 // another client.
419 if (ic == null) {
420 Log.w(TAG, "finishComposingText on inactive InputConnection");
421 return;
422 }
423 ic.finishComposingText();
424 return;
425 }
426 case DO_SEND_KEY_EVENT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700427 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800428 if (ic == null || !isActive()) {
429 Log.w(TAG, "sendKeyEvent on inactive InputConnection");
430 return;
431 }
432 ic.sendKeyEvent((KeyEvent)msg.obj);
433 return;
434 }
435 case DO_CLEAR_META_KEY_STATES: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700436 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437 if (ic == null || !isActive()) {
438 Log.w(TAG, "clearMetaKeyStates on inactive InputConnection");
439 return;
440 }
441 ic.clearMetaKeyStates(msg.arg1);
442 return;
443 }
444 case DO_DELETE_SURROUNDING_TEXT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700445 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446 if (ic == null || !isActive()) {
447 Log.w(TAG, "deleteSurroundingText on inactive InputConnection");
448 return;
449 }
450 ic.deleteSurroundingText(msg.arg1, msg.arg2);
451 return;
452 }
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800453 case DO_DELETE_SURROUNDING_TEXT_IN_CODE_POINTS: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700454 InputConnection ic = getInputConnection();
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800455 if (ic == null || !isActive()) {
456 Log.w(TAG, "deleteSurroundingTextInCodePoints on inactive InputConnection");
457 return;
458 }
459 ic.deleteSurroundingTextInCodePoints(msg.arg1, msg.arg2);
460 return;
461 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 case DO_BEGIN_BATCH_EDIT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700463 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464 if (ic == null || !isActive()) {
465 Log.w(TAG, "beginBatchEdit on inactive InputConnection");
466 return;
467 }
468 ic.beginBatchEdit();
469 return;
470 }
471 case DO_END_BATCH_EDIT: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700472 InputConnection ic = getInputConnection();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 if (ic == null || !isActive()) {
474 Log.w(TAG, "endBatchEdit on inactive InputConnection");
475 return;
476 }
477 ic.endBatchEdit();
478 return;
479 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 case DO_PERFORM_PRIVATE_COMMAND: {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800481 final SomeArgs args = (SomeArgs) msg.obj;
482 try {
483 final String action = (String) args.arg1;
484 final Bundle data = (Bundle) args.arg2;
485 InputConnection ic = getInputConnection();
486 if (ic == null || !isActive()) {
487 Log.w(TAG, "performPrivateCommand on inactive InputConnection");
488 return;
489 }
490 ic.performPrivateCommand(action, data);
491 } finally {
492 args.recycle();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 }
Yohei Yukawa3dd5fbc2017-02-22 20:49:10 -0800494 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800495 }
Yohei Yukawaa277db22014-08-21 18:38:44 -0700496 case DO_REQUEST_UPDATE_CURSOR_ANCHOR_INFO: {
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900497 SomeArgs args = (SomeArgs)msg.obj;
498 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800499 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
500 final int callbackSeq = args.argi6;
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700501 InputConnection ic = getInputConnection();
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900502 if (ic == null || !isActive()) {
503 Log.w(TAG, "requestCursorAnchorInfo on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800504 callback.setRequestUpdateCursorAnchorInfoResult(false, callbackSeq);
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900505 return;
506 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800507 callback.setRequestUpdateCursorAnchorInfoResult(
508 ic.requestCursorUpdates(msg.arg1), callbackSeq);
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900509 } catch (RemoteException e) {
510 Log.w(TAG, "Got RemoteException calling requestCursorAnchorInfo", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800511 } finally {
512 args.recycle();
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900513 }
514 return;
515 }
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700516 case DO_CLOSE_CONNECTION: {
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700517 // Note that we do not need to worry about race condition here, because 1) mFinished
518 // is updated only inside this block, and 2) the code here is running on a Handler
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700519 // hence we assume multiple DO_CLOSE_CONNECTION messages will not be handled at the
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700520 // same time.
521 if (isFinished()) {
522 return;
523 }
524 try {
525 InputConnection ic = getInputConnection();
526 // Note we do NOT check isActive() here, because this is safe
527 // for an IME to call at any time, and we need to allow it
528 // through to clean up our state after the IME has switched to
529 // another client.
530 if (ic == null) {
531 return;
532 }
Yohei Yukawa9f9afe522016-03-30 12:03:51 -0700533 @MissingMethodFlags
534 final int missingMethods = InputConnectionInspector.getMissingMethodFlags(ic);
535 if ((missingMethods & MissingMethodFlags.CLOSE_CONNECTION) == 0) {
536 ic.closeConnection();
Yohei Yukawaaaa38c92016-03-27 23:46:04 -0700537 }
538 } finally {
539 synchronized (mLock) {
540 mInputConnection = null;
541 mFinished = true;
542 }
543 }
544 return;
545 }
Yohei Yukawaadebb522016-06-17 10:10:39 -0700546 case DO_COMMIT_CONTENT: {
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700547 final int flags = msg.arg1;
Yohei Yukawa152944f2016-06-10 19:04:34 -0700548 SomeArgs args = (SomeArgs) msg.obj;
549 try {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800550 final IInputContextCallback callback = (IInputContextCallback) args.arg6;
551 final int callbackSeq = args.argi6;
Yohei Yukawa152944f2016-06-10 19:04:34 -0700552 InputConnection ic = getInputConnection();
553 if (ic == null || !isActive()) {
Yohei Yukawaadebb522016-06-17 10:10:39 -0700554 Log.w(TAG, "commitContent on inactive InputConnection");
Yohei Yukawace82eb22017-02-12 23:16:47 -0800555 callback.setCommitContentResult(false, callbackSeq);
Yohei Yukawa152944f2016-06-10 19:04:34 -0700556 return;
557 }
558 final InputContentInfo inputContentInfo = (InputContentInfo) args.arg1;
559 if (inputContentInfo == null || !inputContentInfo.validate()) {
Yohei Yukawaadebb522016-06-17 10:10:39 -0700560 Log.w(TAG, "commitContent with invalid inputContentInfo="
Yohei Yukawa152944f2016-06-10 19:04:34 -0700561 + inputContentInfo);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800562 callback.setCommitContentResult(false, callbackSeq);
Yohei Yukawa152944f2016-06-10 19:04:34 -0700563 return;
564 }
Yohei Yukawaf3806f52016-06-30 16:27:46 -0700565 final boolean result =
566 ic.commitContent(inputContentInfo, flags, (Bundle) args.arg2);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800567 callback.setCommitContentResult(result, callbackSeq);
Yohei Yukawa152944f2016-06-10 19:04:34 -0700568 } catch (RemoteException e) {
Yohei Yukawaadebb522016-06-17 10:10:39 -0700569 Log.w(TAG, "Got RemoteException calling commitContent", e);
Yohei Yukawace82eb22017-02-12 23:16:47 -0800570 } finally {
571 args.recycle();
Yohei Yukawa152944f2016-06-10 19:04:34 -0700572 }
573 return;
574 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575 }
576 Log.w(TAG, "Unhandled message code: " + msg.what);
577 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 Message obtainMessage(int what) {
580 return mH.obtainMessage(what);
581 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800582
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583 Message obtainMessageII(int what, int arg1, int arg2) {
584 return mH.obtainMessage(what, arg1, arg2);
585 }
Yohei Yukawac89e22a2016-01-13 22:48:14 -0800586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 Message obtainMessageO(int what, Object arg1) {
588 return mH.obtainMessage(what, 0, 0, arg1);
589 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800590
591 Message obtainMessageISC(int what, int arg1, int callbackSeq, IInputContextCallback callback) {
592 final SomeArgs args = SomeArgs.obtain();
593 args.arg6 = callback;
594 args.argi6 = callbackSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595 return mH.obtainMessage(what, arg1, 0, args);
596 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800597
598 Message obtainMessageIISC(int what, int arg1, int arg2, int callbackSeq,
599 IInputContextCallback callback) {
600 final SomeArgs args = SomeArgs.obtain();
601 args.arg6 = callback;
602 args.argi6 = callbackSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 return mH.obtainMessage(what, arg1, arg2, args);
604 }
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900605
Yohei Yukawace82eb22017-02-12 23:16:47 -0800606 Message obtainMessageIOOSC(int what, int arg1, Object objArg1, Object objArg2, int callbackSeq,
Yohei Yukawa152944f2016-06-10 19:04:34 -0700607 IInputContextCallback callback) {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800608 final SomeArgs args = SomeArgs.obtain();
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700609 args.arg1 = objArg1;
610 args.arg2 = objArg2;
Yohei Yukawace82eb22017-02-12 23:16:47 -0800611 args.arg6 = callback;
612 args.argi6 = callbackSeq;
Yohei Yukawa45700fa2016-06-23 17:12:59 -0700613 return mH.obtainMessage(what, arg1, 0, args);
Yohei Yukawa0023d0e2014-07-11 04:13:03 +0900614 }
615
Yohei Yukawace82eb22017-02-12 23:16:47 -0800616 Message obtainMessageIOSC(int what, int arg1, Object arg2, int callbackSeq,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 IInputContextCallback callback) {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800618 final SomeArgs args = SomeArgs.obtain();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800619 args.arg1 = arg2;
Yohei Yukawace82eb22017-02-12 23:16:47 -0800620 args.arg6 = callback;
621 args.argi6 = callbackSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800622 return mH.obtainMessage(what, arg1, 0, args);
623 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800624
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800625 Message obtainMessageIO(int what, int arg1, Object arg2) {
626 return mH.obtainMessage(what, arg1, 0, arg2);
627 }
Yohei Yukawace82eb22017-02-12 23:16:47 -0800628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 Message obtainMessageOO(int what, Object arg1, Object arg2) {
Yohei Yukawace82eb22017-02-12 23:16:47 -0800630 final SomeArgs args = SomeArgs.obtain();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800631 args.arg1 = arg1;
632 args.arg2 = arg2;
633 return mH.obtainMessage(what, 0, 0, args);
634 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635}