OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 package org.chromium.content.browser.input; | |
6 | |
7 import android.text.Editable; | |
8 import android.text.InputType; | |
9 import android.text.Selection; | |
10 import android.util.StringBuilderPrinter; | |
11 import android.view.View; | |
12 import android.view.inputmethod.BaseInputConnection; | |
13 import android.view.inputmethod.CorrectionInfo; | |
14 import android.view.inputmethod.EditorInfo; | |
15 | |
16 import org.chromium.base.ThreadUtils; | |
17 import org.chromium.blink_public.web.WebTextInputFlags; | |
18 import org.chromium.ui.base.ime.TextInputType; | |
19 | |
20 import java.util.Locale; | |
21 | |
22 /** | |
23 * Utilities for IME such as computing outAttrs, and dumping object information. | |
24 */ | |
25 public class ImeUtils { | |
26 /** | |
27 * Compute {@link EditorInfo} based on the given parameters. This is needed for | |
28 * {@link View#onCreateInputConnection(EditorInfo)}. | |
29 * | |
30 * @param inputType Type defined in {@link TextInputType}. | |
31 * @param inputFlags Flags defined in {@link WebTextInputFlags}. | |
32 * @param initialSelStart The initial selection start position. | |
33 * @param initialSelEnd The initial selection end position. | |
34 * @param outAttrs An instance of {@link EditorInfo} that we are going to ch ange. | |
35 */ | |
36 public static void computeEditorInfo(int inputType, int inputFlags, int init ialSelStart, | |
37 int initialSelEnd, EditorInfo outAttrs) { | |
38 outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN | EditorInfo.IME _FLAG_NO_EXTRACT_UI; | |
39 outAttrs.inputType = | |
40 EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_WEB_ EDIT_TEXT; | |
41 | |
42 if ((inputFlags & WebTextInputFlags.AutocompleteOff) != 0) { | |
43 outAttrs.inputType |= EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS; | |
44 } | |
45 | |
46 if (inputType == TextInputType.TEXT) { | |
47 // Normal text field | |
48 outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO; | |
49 if ((inputFlags & WebTextInputFlags.AutocorrectOff) == 0) { | |
50 outAttrs.inputType |= EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT; | |
51 } | |
52 } else if (inputType == TextInputType.TEXT_AREA | |
53 || inputType == TextInputType.CONTENT_EDITABLE) { | |
54 outAttrs.inputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE; | |
55 if ((inputFlags & WebTextInputFlags.AutocorrectOff) == 0) { | |
56 outAttrs.inputType |= EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT; | |
57 } | |
58 outAttrs.imeOptions |= EditorInfo.IME_ACTION_NONE; | |
59 } else if (inputType == TextInputType.PASSWORD) { | |
60 // Password | |
palmer
2016/02/25 23:49:55
Nit: This is probably just me, but, I don't think
Changwan Ryu
2016/02/26 02:41:19
Removed in the follow-up CL: https://codereview.ch
| |
61 outAttrs.inputType = | |
62 InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WE B_PASSWORD; | |
63 outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO; | |
64 } else if (inputType == TextInputType.SEARCH) { | |
65 // Search | |
66 outAttrs.imeOptions |= EditorInfo.IME_ACTION_SEARCH; | |
67 } else if (inputType == TextInputType.URL) { | |
68 // Url | |
69 outAttrs.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT _VARIATION_URI; | |
70 outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO; | |
71 } else if (inputType == TextInputType.EMAIL) { | |
72 // Email | |
73 outAttrs.inputType = | |
74 InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_WE B_EMAIL_ADDRESS; | |
75 outAttrs.imeOptions |= EditorInfo.IME_ACTION_GO; | |
76 } else if (inputType == TextInputType.TELEPHONE) { | |
77 // Telephone | |
78 // Number and telephone do not have both a Tab key and an | |
79 // action in default OSK, so set the action to NEXT | |
80 outAttrs.inputType = InputType.TYPE_CLASS_PHONE; | |
81 outAttrs.imeOptions |= EditorInfo.IME_ACTION_NEXT; | |
82 } else if (inputType == TextInputType.NUMBER) { | |
83 // Number | |
84 outAttrs.inputType = InputType.TYPE_CLASS_NUMBER | |
85 | InputType.TYPE_NUMBER_VARIATION_NORMAL | InputType.TYPE_NU MBER_FLAG_DECIMAL; | |
86 outAttrs.imeOptions |= EditorInfo.IME_ACTION_NEXT; | |
87 } | |
88 | |
89 // Handling of autocapitalize. Blink will send the flag taking into acco unt the element's | |
90 // type. This is not using AutocapitalizeNone because Android does not a utocapitalize by | |
91 // default and there is no way to express no capitalization. | |
92 // Autocapitalize is meant as a hint to the virtual keyboard. | |
93 if ((inputFlags & WebTextInputFlags.AutocapitalizeCharacters) != 0) { | |
94 outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS; | |
95 } else if ((inputFlags & WebTextInputFlags.AutocapitalizeWords) != 0) { | |
96 outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_CAP_WORDS; | |
97 } else if ((inputFlags & WebTextInputFlags.AutocapitalizeSentences) != 0 ) { | |
98 outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_CAP_SENTENCES; | |
99 } | |
100 // Content editable doesn't use autocapitalize so we need to set it manu ally. | |
101 if (inputType == TextInputType.CONTENT_EDITABLE) { | |
102 outAttrs.inputType |= InputType.TYPE_TEXT_FLAG_CAP_SENTENCES; | |
103 } | |
104 | |
105 outAttrs.initialSelStart = initialSelStart; | |
106 outAttrs.initialSelEnd = initialSelEnd; | |
107 } | |
108 | |
109 public static String getEditorInfoDebugString(EditorInfo editorInfo) { | |
110 StringBuilder builder = new StringBuilder(); | |
111 StringBuilderPrinter printer = new StringBuilderPrinter(builder); | |
112 editorInfo.dump(printer, ""); | |
113 return builder.toString(); | |
114 } | |
115 | |
116 public static String getEditableDebugString(Editable editable) { | |
117 return String.format(Locale.US, "Editable {[%s] SEL[%d %d] COM[%d %d]}", | |
118 editable.toString(), Selection.getSelectionStart(editable), | |
119 Selection.getSelectionEnd(editable), | |
120 BaseInputConnection.getComposingSpanStart(editable), | |
121 BaseInputConnection.getComposingSpanEnd(editable)); | |
122 } | |
123 | |
124 /** | |
125 * Dump the given {@CorrectionInfo} into class. | |
palmer
2016/02/25 23:49:55
Nit: This comment doesn't make sense to me. But, I
Changwan Ryu
2016/02/26 02:41:19
Refined the comment in the follow-up CL. I think i
| |
126 * @param correctionInfo | |
127 * @return User-readable {@CorrectionInfo}. | |
128 */ | |
129 static String getCorrectInfoDebugString(CorrectionInfo correctionInfo) { | |
palmer
2016/02/25 23:49:55
Typo: Should be |getCorrectionInfoDebugString|.
Changwan Ryu
2016/02/26 02:41:19
Done in the follow-up CL.
| |
130 // TODO(changwan): implement it properly if needed. | |
131 return correctionInfo.toString(); | |
132 } | |
133 | |
134 // TODO(changwan): remove these once implementation becomes stable. | |
palmer
2016/02/25 23:49:55
Always a good idea to tie TODOs to bugs filed in t
Changwan Ryu
2016/02/26 02:41:19
Actually, I changed my mind. I don't think we shou
| |
135 static void checkCondition(boolean value) { | |
136 if (!value) { | |
137 throw new AssertionError(); | |
138 } | |
139 } | |
140 | |
141 static void checkCondition(String msg, boolean value) { | |
142 if (!value) { | |
143 throw new AssertionError(msg); | |
144 } | |
145 } | |
146 | |
147 static void checkOnUiThread() { | |
148 checkCondition("Should be on UI thread.", ThreadUtils.runningOnUiThread( )); | |
149 } | |
150 } | |
OLD | NEW |