1 /* 2 * Copyright (C) 2011 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 17 package com.android.inputmethod.latin; 18 19 import android.text.InputType; 20 import android.util.Log; 21 import android.view.inputmethod.EditorInfo; 22 23 /** 24 * Class to hold attributes of the input field. 25 */ 26 public final class InputAttributes { 27 private final String TAG = InputAttributes.class.getSimpleName(); 28 29 final public boolean mInputTypeNoAutoCorrect; 30 final public boolean mIsSettingsSuggestionStripOn; 31 final public boolean mApplicationSpecifiedCompletionOn; 32 final public boolean mShouldInsertSpacesAutomatically; 33 final private int mInputType; 34 InputAttributes(final EditorInfo editorInfo, final boolean isFullscreenMode)35 public InputAttributes(final EditorInfo editorInfo, final boolean isFullscreenMode) { 36 final int inputType = null != editorInfo ? editorInfo.inputType : 0; 37 final int inputClass = inputType & InputType.TYPE_MASK_CLASS; 38 mInputType = inputType; 39 if (inputClass != InputType.TYPE_CLASS_TEXT) { 40 // If we are not looking at a TYPE_CLASS_TEXT field, the following strange 41 // cases may arise, so we do a couple sanity checks for them. If it's a 42 // TYPE_CLASS_TEXT field, these special cases cannot happen, by construction 43 // of the flags. 44 if (null == editorInfo) { 45 Log.w(TAG, "No editor info for this field. Bug?"); 46 } else if (InputType.TYPE_NULL == inputType) { 47 // TODO: We should honor TYPE_NULL specification. 48 Log.i(TAG, "InputType.TYPE_NULL is specified"); 49 } else if (inputClass == 0) { 50 // TODO: is this check still necessary? 51 Log.w(TAG, String.format("Unexpected input class: inputType=0x%08x" 52 + " imeOptions=0x%08x", 53 inputType, editorInfo.imeOptions)); 54 } 55 mIsSettingsSuggestionStripOn = false; 56 mInputTypeNoAutoCorrect = false; 57 mApplicationSpecifiedCompletionOn = false; 58 mShouldInsertSpacesAutomatically = false; 59 } else { 60 final int variation = inputType & InputType.TYPE_MASK_VARIATION; 61 final boolean flagNoSuggestions = 62 0 != (inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); 63 final boolean flagMultiLine = 64 0 != (inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE); 65 final boolean flagAutoCorrect = 66 0 != (inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT); 67 final boolean flagAutoComplete = 68 0 != (inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE); 69 70 // TODO: Have a helper method in InputTypeUtils 71 // Make sure that passwords are not displayed in {@link SuggestionStripView}. 72 if (InputTypeUtils.isPasswordInputType(inputType) 73 || InputTypeUtils.isVisiblePasswordInputType(inputType) 74 || InputTypeUtils.isEmailVariation(variation) 75 || InputType.TYPE_TEXT_VARIATION_URI == variation 76 || InputType.TYPE_TEXT_VARIATION_FILTER == variation 77 || flagNoSuggestions 78 || flagAutoComplete) { 79 mIsSettingsSuggestionStripOn = false; 80 } else { 81 mIsSettingsSuggestionStripOn = true; 82 } 83 84 mShouldInsertSpacesAutomatically = InputTypeUtils.isAutoSpaceFriendlyType(inputType); 85 86 // If it's a browser edit field and auto correct is not ON explicitly, then 87 // disable auto correction, but keep suggestions on. 88 // If NO_SUGGESTIONS is set, don't do prediction. 89 // If it's not multiline and the autoCorrect flag is not set, then don't correct 90 if ((variation == InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT 91 && !flagAutoCorrect) 92 || flagNoSuggestions 93 || (!flagAutoCorrect && !flagMultiLine)) { 94 mInputTypeNoAutoCorrect = true; 95 } else { 96 mInputTypeNoAutoCorrect = false; 97 } 98 99 mApplicationSpecifiedCompletionOn = flagAutoComplete && isFullscreenMode; 100 } 101 } 102 isSameInputType(final EditorInfo editorInfo)103 public boolean isSameInputType(final EditorInfo editorInfo) { 104 return editorInfo.inputType == mInputType; 105 } 106 107 @SuppressWarnings("unused") dumpFlags(final int inputType)108 private void dumpFlags(final int inputType) { 109 Log.i(TAG, "Input class:"); 110 final int inputClass = inputType & InputType.TYPE_MASK_CLASS; 111 if (inputClass == InputType.TYPE_CLASS_TEXT) 112 Log.i(TAG, " TYPE_CLASS_TEXT"); 113 if (inputClass == InputType.TYPE_CLASS_PHONE) 114 Log.i(TAG, " TYPE_CLASS_PHONE"); 115 if (inputClass == InputType.TYPE_CLASS_NUMBER) 116 Log.i(TAG, " TYPE_CLASS_NUMBER"); 117 if (inputClass == InputType.TYPE_CLASS_DATETIME) 118 Log.i(TAG, " TYPE_CLASS_DATETIME"); 119 Log.i(TAG, "Variation:"); 120 switch (InputType.TYPE_MASK_VARIATION & inputType) { 121 case InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS: 122 Log.i(TAG, " TYPE_TEXT_VARIATION_EMAIL_ADDRESS"); 123 break; 124 case InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT: 125 Log.i(TAG, " TYPE_TEXT_VARIATION_EMAIL_SUBJECT"); 126 break; 127 case InputType.TYPE_TEXT_VARIATION_FILTER: 128 Log.i(TAG, " TYPE_TEXT_VARIATION_FILTER"); 129 break; 130 case InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE: 131 Log.i(TAG, " TYPE_TEXT_VARIATION_LONG_MESSAGE"); 132 break; 133 case InputType.TYPE_TEXT_VARIATION_NORMAL: 134 Log.i(TAG, " TYPE_TEXT_VARIATION_NORMAL"); 135 break; 136 case InputType.TYPE_TEXT_VARIATION_PASSWORD: 137 Log.i(TAG, " TYPE_TEXT_VARIATION_PASSWORD"); 138 break; 139 case InputType.TYPE_TEXT_VARIATION_PERSON_NAME: 140 Log.i(TAG, " TYPE_TEXT_VARIATION_PERSON_NAME"); 141 break; 142 case InputType.TYPE_TEXT_VARIATION_PHONETIC: 143 Log.i(TAG, " TYPE_TEXT_VARIATION_PHONETIC"); 144 break; 145 case InputType.TYPE_TEXT_VARIATION_POSTAL_ADDRESS: 146 Log.i(TAG, " TYPE_TEXT_VARIATION_POSTAL_ADDRESS"); 147 break; 148 case InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE: 149 Log.i(TAG, " TYPE_TEXT_VARIATION_SHORT_MESSAGE"); 150 break; 151 case InputType.TYPE_TEXT_VARIATION_URI: 152 Log.i(TAG, " TYPE_TEXT_VARIATION_URI"); 153 break; 154 case InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD: 155 Log.i(TAG, " TYPE_TEXT_VARIATION_VISIBLE_PASSWORD"); 156 break; 157 case InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT: 158 Log.i(TAG, " TYPE_TEXT_VARIATION_WEB_EDIT_TEXT"); 159 break; 160 case InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS: 161 Log.i(TAG, " TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS"); 162 break; 163 case InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD: 164 Log.i(TAG, " TYPE_TEXT_VARIATION_WEB_PASSWORD"); 165 break; 166 default: 167 Log.i(TAG, " Unknown variation"); 168 break; 169 } 170 Log.i(TAG, "Flags:"); 171 if (0 != (inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS)) 172 Log.i(TAG, " TYPE_TEXT_FLAG_NO_SUGGESTIONS"); 173 if (0 != (inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE)) 174 Log.i(TAG, " TYPE_TEXT_FLAG_MULTI_LINE"); 175 if (0 != (inputType & InputType.TYPE_TEXT_FLAG_IME_MULTI_LINE)) 176 Log.i(TAG, " TYPE_TEXT_FLAG_IME_MULTI_LINE"); 177 if (0 != (inputType & InputType.TYPE_TEXT_FLAG_CAP_WORDS)) 178 Log.i(TAG, " TYPE_TEXT_FLAG_CAP_WORDS"); 179 if (0 != (inputType & InputType.TYPE_TEXT_FLAG_CAP_SENTENCES)) 180 Log.i(TAG, " TYPE_TEXT_FLAG_CAP_SENTENCES"); 181 if (0 != (inputType & InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS)) 182 Log.i(TAG, " TYPE_TEXT_FLAG_CAP_CHARACTERS"); 183 if (0 != (inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT)) 184 Log.i(TAG, " TYPE_TEXT_FLAG_AUTO_CORRECT"); 185 if (0 != (inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE)) 186 Log.i(TAG, " TYPE_TEXT_FLAG_AUTO_COMPLETE"); 187 } 188 189 // Pretty print 190 @Override toString()191 public String toString() { 192 return "\n mInputTypeNoAutoCorrect = " + mInputTypeNoAutoCorrect 193 + "\n mIsSettingsSuggestionStripOn = " + mIsSettingsSuggestionStripOn 194 + "\n mApplicationSpecifiedCompletionOn = " + mApplicationSpecifiedCompletionOn; 195 } 196 inPrivateImeOptions(String packageName, String key, EditorInfo editorInfo)197 public static boolean inPrivateImeOptions(String packageName, String key, 198 EditorInfo editorInfo) { 199 if (editorInfo == null) return false; 200 final String findingKey = (packageName != null) ? packageName + "." + key 201 : key; 202 return StringUtils.containsInCsv(findingKey, editorInfo.privateImeOptions); 203 } 204 } 205