Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: content/public/android/java/src/org/chromium/content/browser/ImeAdapter.java

Issue 11783088: Split Date/Time picker values from IME processing since date/time related form values have been com… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moved header file out of public, applied renaming suggestions. Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.content.browser; 5 package org.chromium.content.browser;
6 6
7 import android.content.Context; 7 import android.content.Context;
8 import android.os.Handler; 8 import android.os.Handler;
9 import android.os.ResultReceiver; 9 import android.os.ResultReceiver;
10 import android.text.Editable; 10 import android.text.Editable;
11 import android.text.InputType; 11 import android.text.InputType;
12 import android.text.Selection; 12 import android.text.Selection;
13 import android.view.KeyEvent; 13 import android.view.KeyEvent;
14 import android.view.View; 14 import android.view.View;
15 import android.view.inputmethod.BaseInputConnection; 15 import android.view.inputmethod.BaseInputConnection;
16 import android.view.inputmethod.EditorInfo; 16 import android.view.inputmethod.EditorInfo;
17 import android.view.inputmethod.ExtractedText; 17 import android.view.inputmethod.ExtractedText;
18 import android.view.inputmethod.ExtractedTextRequest; 18 import android.view.inputmethod.ExtractedTextRequest;
19 import android.view.inputmethod.InputMethodManager; 19 import android.view.inputmethod.InputMethodManager;
20 20
21 import org.chromium.base.CalledByNative; 21 import org.chromium.base.CalledByNative;
22 import org.chromium.base.JNINamespace; 22 import org.chromium.base.JNINamespace;
23 23
24 // We have to adapt and plumb android IME service and chrome text input API. 24 /**
25 // ImeAdapter provides an interface in both ways native <-> java: 25 We have to adapt and plumb android IME service and chrome text input API.
26 // 1. InputConnectionAdapter notifies native code of text composition state and 26 ImeAdapter provides an interface in both ways native <-> java:
27 // dispatch key events from java -> WebKit. 27 1. InputConnectionAdapter notifies native code of text composition state and
28 // 2. Native ImeAdapter notifies java side to clear composition text. 28 dispatch key events from java -> WebKit.
29 // 29 2. Native ImeAdapter notifies java side to clear composition text.
30 // The basic flow is: 30
31 // 1. Intercept dispatchKeyEventPreIme() to record the current key event, but do 31 The basic flow is:
32 // nothing else. 32 1. Intercept dispatchKeyEventPreIme() to record the current key event, but do
33 // 2. When InputConnectionAdapter gets called with composition or result text: 33 nothing else.
34 // a) If a key event has been recorded in dispatchKeyEventPreIme() and we 34 2. When InputConnectionAdapter gets called with composition or result text:
35 // receive a result text with single character, then we probably need to 35 a) If a key event has been recorded in dispatchKeyEventPreIme() and we
36 // send the result text as a Char event rather than a ConfirmComposition 36 receive a result text with single character, then we probably need to
37 // event. So we need to dispatch the recorded key event followed by a 37 send the result text as a Char event rather than a ConfirmComposition
38 // synthetic Char event. 38 event. So we need to dispatch the recorded key event followed by a
39 // b) If we receive a composition text or a result text with more than one 39 synthetic Char event.
40 // characters, then no matter if we recorded a key event or not in 40 b) If we receive a composition text or a result text with more than one
41 // dispatchKeyEventPreIme(), we just need to dispatch a synthetic key 41 characters, then no matter if we recorded a key event or not in
42 // event with special keycode 229, and then dispatch the composition or 42 dispatchKeyEventPreIme(), we just need to dispatch a synthetic key
43 // result text. 43 event with special keycode 229, and then dispatch the composition or
44 // 3. Intercept dispatchKeyEvent() method for key events not handled by IME, we 44 result text.
45 // need to dispatch them to webkit and check webkit's reply. Then inject a 45 3. Intercept dispatchKeyEvent() method for key events not handled by IME, we
46 // new key event for further processing if webkit didn't handle it. 46 need to dispatch them to WebKit and check webkit's reply. Then inject a
47 new key event for further processing if WebKit didn't handle it.
48 */
47 @JNINamespace("content") 49 @JNINamespace("content")
48 class ImeAdapter { 50 class ImeAdapter {
49 interface ViewEmbedder { 51 interface ViewEmbedder {
50 /** 52 /**
51 * @param isFinish whether the event is occuring because input is finish ed. 53 * @param isFinish whether the event is occurring because input is finis hed.
52 */ 54 */
53 public void onImeEvent(boolean isFinish); 55 public void onImeEvent(boolean isFinish);
54 public void onSetFieldValue(); 56 public void onSetFieldValue();
55 public void onDismissInput(); 57 public void onDismissInput();
56 public View getAttachedView(); 58 public View getAttachedView();
57 public ResultReceiver getNewShowKeyboardReceiver(); 59 public ResultReceiver getNewShowKeyboardReceiver();
58 } 60 }
59 61
60 static final int COMPOSITION_KEY_CODE = 229; 62 static final int COMPOSITION_KEY_CODE = 229;
61 63
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 sTextInputTypeText = textInputTypeText; 106 sTextInputTypeText = textInputTypeText;
105 sTextInputTypeTextArea = textInputTypeTextArea; 107 sTextInputTypeTextArea = textInputTypeTextArea;
106 sTextInputTypePassword = textInputTypePassword; 108 sTextInputTypePassword = textInputTypePassword;
107 sTextInputTypeSearch = textInputTypeSearch; 109 sTextInputTypeSearch = textInputTypeSearch;
108 sTextInputTypeUrl = textInputTypeUrl; 110 sTextInputTypeUrl = textInputTypeUrl;
109 sTextInputTypeEmail = textInputTypeEmail; 111 sTextInputTypeEmail = textInputTypeEmail;
110 sTextInputTypeTel = textInputTypeTel; 112 sTextInputTypeTel = textInputTypeTel;
111 sTextInputTypeNumber = textInputTypeNumber; 113 sTextInputTypeNumber = textInputTypeNumber;
112 sTextInputTypeWeek = textInputTypeWeek; 114 sTextInputTypeWeek = textInputTypeWeek;
113 sTextInputTypeContentEditable = textInputTypeContentEditable; 115 sTextInputTypeContentEditable = textInputTypeContentEditable;
114 InputDialogContainer.initializeInputTypes(textInputTypeDate, textInputTy peDateTime,
115 textInputTypeDateTimeLocal, textInputTypeMonth, textInputTypeTim e);
116 } 116 }
117 117
118 private int mNativeImeAdapterAndroid; 118 private int mNativeImeAdapterAndroid;
119 private int mTextInputType; 119 private int mTextInputType;
120 private int mPreImeEventCount; 120 private int mPreImeEventCount;
121 121
122 private Context mContext; 122 private Context mContext;
123 private SelectionHandleController mSelectionHandleController; 123 private SelectionHandleController mSelectionHandleController;
124 private InsertionHandleController mInsertionHandleController; 124 private InsertionHandleController mInsertionHandleController;
125 private AdapterInputConnection mInputConnection; 125 private AdapterInputConnection mInputConnection;
126 private ViewEmbedder mViewEmbedder; 126 private ViewEmbedder mViewEmbedder;
127 private Handler mHandler; 127 private Handler mHandler;
128 private InputDialogContainer mInputDialogContainer;
129 128
130 private class DelayedDismissInput implements Runnable { 129 private class DelayedDismissInput implements Runnable {
131 private int mNativeImeAdapter; 130 private int mNativeImeAdapter;
132 131
133 DelayedDismissInput(int nativeImeAdapter) { 132 DelayedDismissInput(int nativeImeAdapter) {
134 mNativeImeAdapter = nativeImeAdapter; 133 mNativeImeAdapter = nativeImeAdapter;
135 } 134 }
136 135
137 @Override 136 @Override
138 public void run() { 137 public void run() {
(...skipping 12 matching lines...) Expand all
151 private static final int INPUT_DISMISS_DELAY = 150; 150 private static final int INPUT_DISMISS_DELAY = 150;
152 151
153 ImeAdapter(Context context, SelectionHandleController selectionHandleControl ler, 152 ImeAdapter(Context context, SelectionHandleController selectionHandleControl ler,
154 InsertionHandleController insertionHandleController, ViewEmbedder em bedder) { 153 InsertionHandleController insertionHandleController, ViewEmbedder em bedder) {
155 mPreImeEventCount = 0; 154 mPreImeEventCount = 0;
156 mContext = context; 155 mContext = context;
157 mSelectionHandleController = selectionHandleController; 156 mSelectionHandleController = selectionHandleController;
158 mInsertionHandleController = insertionHandleController; 157 mInsertionHandleController = insertionHandleController;
159 mViewEmbedder = embedder; 158 mViewEmbedder = embedder;
160 mHandler = new Handler(); 159 mHandler = new Handler();
161 mInputDialogContainer = new InputDialogContainer(context,
162 new InputDialogContainer.InputActionDelegate() {
163
164 @Override
165 public void replaceDateTime(String text) {
166 mViewEmbedder.onSetFieldValue();
167 nativeReplaceDateTime(mNativeImeAdapterAndroid, text);
168 }
169
170 @Override
171 public void cancelDateTimeDialog() {
172 nativeCancelDialog(mNativeImeAdapterAndroid);
173 }
174 });
175 } 160 }
176 161
177 boolean isFor(int nativeImeAdapter, int textInputType) { 162 boolean isFor(int nativeImeAdapter, int textInputType) {
178 return mNativeImeAdapterAndroid == nativeImeAdapter && 163 return mNativeImeAdapterAndroid == nativeImeAdapter &&
179 mTextInputType == textInputType; 164 mTextInputType == textInputType;
180 } 165 }
181 166
182 void attachAndShowIfNeeded(int nativeImeAdapter, int textInputType, 167 void attachAndShowIfNeeded(int nativeImeAdapter, int textInputType,
183 String text, boolean showIfNeeded) { 168 String text, boolean showIfNeeded) {
184 mHandler.removeCallbacks(mDismissInput); 169 mHandler.removeCallbacks(mDismissInput);
(...skipping 12 matching lines...) Expand all
197 mHandler.postDelayed(mDismissInput, INPUT_DISMISS_DELAY); 182 mHandler.postDelayed(mDismissInput, INPUT_DISMISS_DELAY);
198 return; 183 return;
199 } 184 }
200 185
201 int previousType = mTextInputType; 186 int previousType = mTextInputType;
202 attach(nativeImeAdapter, textInputType); 187 attach(nativeImeAdapter, textInputType);
203 188
204 InputMethodManager manager = (InputMethodManager) 189 InputMethodManager manager = (InputMethodManager)
205 mContext.getSystemService(Context.INPUT_METHOD_SERVICE); 190 mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
206 191
207 if (hasTextInputType()) { 192 manager.restartInput(mViewEmbedder.getAttachedView());
208 manager.restartInput(mViewEmbedder.getAttachedView()); 193 if (showIfNeeded) {
209 // If type has changed from dialog to text, show even if showIfN eeded is not true. 194 showKeyboard();
210 if (showIfNeeded || mInputDialogContainer.isDialogShowing()) {
211 showKeyboard();
212 }
213 } else if (hasDialogInputType()) {
214 // If type has changed from text to dialog, show even if showIfN eeded is not true.
215 if (showIfNeeded || isTextInputType(previousType)) {
216 // Make sure the keyboard is dismissed before displaying the dialog.
217 dismissInput(false);
218 mInsertionHandleController.hideAndDisallowAutomaticShowing() ;
219 mInputDialogContainer.showDialog(text, textInputType);
220 }
221 } 195 }
222 } else if (hasInputType()) { 196 } else if (hasInputType()) {
223 if (!mInputDialogContainer.isDialogShowing() && showIfNeeded) { 197 showKeyboard();
224 if (hasDialogInputType()) {
225 mInsertionHandleController.hideAndDisallowAutomaticShowing() ;
226 mInputDialogContainer.showDialog(text, textInputType);
227 } else {
228 showKeyboard();
229 }
230 }
231 } 198 }
232 } 199 }
233 200
234 void attach(int nativeImeAdapter, int textInputType) { 201 void attach(int nativeImeAdapter, int textInputType) {
235 mNativeImeAdapterAndroid = nativeImeAdapter; 202 mNativeImeAdapterAndroid = nativeImeAdapter;
236 mTextInputType = textInputType; 203 mTextInputType = textInputType;
237 nativeAttachImeAdapter(mNativeImeAdapterAndroid); 204 nativeAttachImeAdapter(mNativeImeAdapterAndroid);
238 } 205 }
239 206
240 /** 207 /**
(...skipping 10 matching lines...) Expand all
251 218
252 /** 219 /**
253 * Used to check whether the native counterpart of the ImeAdapter has been a ttached yet. 220 * Used to check whether the native counterpart of the ImeAdapter has been a ttached yet.
254 * @return Whether native ImeAdapter has been attached and its pointer is cu rrently nonzero. 221 * @return Whether native ImeAdapter has been attached and its pointer is cu rrently nonzero.
255 */ 222 */
256 boolean isNativeImeAdapterAttached() { 223 boolean isNativeImeAdapterAttached() {
257 return mNativeImeAdapterAndroid != 0; 224 return mNativeImeAdapterAndroid != 0;
258 } 225 }
259 226
260 private void showKeyboard() { 227 private void showKeyboard() {
261 mInputDialogContainer.dismissDialog();
262 InputMethodManager manager = (InputMethodManager) 228 InputMethodManager manager = (InputMethodManager)
263 mContext.getSystemService(Context.INPUT_METHOD_SERVICE); 229 mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
264 manager.showSoftInput(mViewEmbedder.getAttachedView(), 0, 230 manager.showSoftInput(mViewEmbedder.getAttachedView(), 0,
265 mViewEmbedder.getNewShowKeyboardReceiver()); 231 mViewEmbedder.getNewShowKeyboardReceiver());
266 } 232 }
267 233
268 private void dismissInput(boolean unzoomIfNeeded) { 234 private void dismissInput(boolean unzoomIfNeeded) {
269 hideKeyboard(unzoomIfNeeded); 235 hideKeyboard(unzoomIfNeeded);
270 mViewEmbedder.onDismissInput(); 236 mViewEmbedder.onDismissInput();
271 } 237 }
(...skipping 19 matching lines...) Expand all
291 } 257 }
292 258
293 static boolean isTextInputType(int type) { 259 static boolean isTextInputType(int type) {
294 return type != sTextInputTypeNone && !InputDialogContainer.isDialogInput Type(type); 260 return type != sTextInputTypeNone && !InputDialogContainer.isDialogInput Type(type);
295 } 261 }
296 262
297 boolean hasTextInputType() { 263 boolean hasTextInputType() {
298 return isTextInputType(mTextInputType); 264 return isTextInputType(mTextInputType);
299 } 265 }
300 266
301 boolean hasDialogInputType() {
302 return InputDialogContainer.isDialogInputType(mTextInputType);
303 }
304
305 void dispatchKeyEventPreIme(KeyEvent event) { 267 void dispatchKeyEventPreIme(KeyEvent event) {
306 // We only register that a key was pressed, but we don't actually interc ept 268 // We only register that a key was pressed, but we don't actually interc ept
307 // it. 269 // it.
308 ++mPreImeEventCount; 270 ++mPreImeEventCount;
309 } 271 }
310 272
311 boolean dispatchKeyEvent(KeyEvent event) { 273 boolean dispatchKeyEvent(KeyEvent event) {
312 mPreImeEventCount = 0; 274 mPreImeEventCount = 0;
313 return translateAndSendNativeEvents(event); 275 return translateAndSendNativeEvents(event);
314 } 276 }
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 int action, int modifiers, long timestampMs, int keyCode, boolean is SystemKey, 733 int action, int modifiers, long timestampMs, int keyCode, boolean is SystemKey,
772 int unicodeChar); 734 int unicodeChar);
773 735
774 private native void nativeSetComposingText(int nativeImeAdapterAndroid, Stri ng text, 736 private native void nativeSetComposingText(int nativeImeAdapterAndroid, Stri ng text,
775 int newCursorPosition); 737 int newCursorPosition);
776 738
777 private native void nativeCommitText(int nativeImeAdapterAndroid, String tex t); 739 private native void nativeCommitText(int nativeImeAdapterAndroid, String tex t);
778 740
779 private native void nativeAttachImeAdapter(int nativeImeAdapterAndroid); 741 private native void nativeAttachImeAdapter(int nativeImeAdapterAndroid);
780 742
781 private native void nativeReplaceDateTime(int nativeImeAdapterAndroid, Strin g text);
782
783 private native void nativeCancelDialog(int nativeImeAdapterAndroid);
784
785 private native void nativeSetEditableSelectionOffsets(int nativeImeAdapterAn droid, 743 private native void nativeSetEditableSelectionOffsets(int nativeImeAdapterAn droid,
786 int start, int end); 744 int start, int end);
787 745
788 private native void nativeSetComposingRegion(int nativeImeAdapterAndroid, in t start, int end); 746 private native void nativeSetComposingRegion(int nativeImeAdapterAndroid, in t start, int end);
789 747
790 private native void nativeDeleteSurroundingText(int nativeImeAdapterAndroid, 748 private native void nativeDeleteSurroundingText(int nativeImeAdapterAndroid,
791 int before, int after); 749 int before, int after);
792 750
793 private native void nativeUnselect(int nativeImeAdapterAndroid); 751 private native void nativeUnselect(int nativeImeAdapterAndroid);
794 private native void nativeSelectAll(int nativeImeAdapterAndroid); 752 private native void nativeSelectAll(int nativeImeAdapterAndroid);
795 private native void nativeCut(int nativeImeAdapterAndroid); 753 private native void nativeCut(int nativeImeAdapterAndroid);
796 private native void nativeCopy(int nativeImeAdapterAndroid); 754 private native void nativeCopy(int nativeImeAdapterAndroid);
797 private native void nativePaste(int nativeImeAdapterAndroid); 755 private native void nativePaste(int nativeImeAdapterAndroid);
798 } 756 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698