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