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 |
| 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. |
| 126 * @param correctionInfo |
| 127 * @return User-readable {@CorrectionInfo}. |
| 128 */ |
| 129 static String getCorrectInfoDebugString(CorrectionInfo correctionInfo) { |
| 130 // TODO(changwan): implement it properly if needed. |
| 131 return correctionInfo.toString(); |
| 132 } |
| 133 |
| 134 // TODO(changwan): remove these once implementation becomes stable. |
| 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 |