1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17package com.android.inputmethod.latin; 18 19import android.text.InputType; 20import android.util.Log; 21import android.view.inputmethod.EditorInfo; 22 23/** 24 * Class to hold attributes of the input field. 25 */ 26public 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 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 103 public boolean isSameInputType(final EditorInfo editorInfo) { 104 return editorInfo.inputType == mInputType; 105 } 106 107 @SuppressWarnings("unused") 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 if (0 != (inputType & InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS)) 121 Log.i(TAG, " TYPE_TEXT_VARIATION_EMAIL_ADDRESS"); 122 if (0 != (inputType & InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT)) 123 Log.i(TAG, " TYPE_TEXT_VARIATION_EMAIL_SUBJECT"); 124 if (0 != (inputType & InputType.TYPE_TEXT_VARIATION_FILTER)) 125 Log.i(TAG, " TYPE_TEXT_VARIATION_FILTER"); 126 if (0 != (inputType & InputType.TYPE_TEXT_VARIATION_LONG_MESSAGE)) 127 Log.i(TAG, " TYPE_TEXT_VARIATION_LONG_MESSAGE"); 128 if (0 != (inputType & InputType.TYPE_TEXT_VARIATION_NORMAL)) 129 Log.i(TAG, " TYPE_TEXT_VARIATION_NORMAL"); 130 if (0 != (inputType & InputType.TYPE_TEXT_VARIATION_PASSWORD)) 131 Log.i(TAG, " TYPE_TEXT_VARIATION_PASSWORD"); 132 if (0 != (inputType & InputType.TYPE_TEXT_VARIATION_PERSON_NAME)) 133 Log.i(TAG, " TYPE_TEXT_VARIATION_PERSON_NAME"); 134 if (0 != (inputType & InputType.TYPE_TEXT_VARIATION_PHONETIC)) 135 Log.i(TAG, " TYPE_TEXT_VARIATION_PHONETIC"); 136 if (0 != (inputType & InputType.TYPE_TEXT_VARIATION_POSTAL_ADDRESS)) 137 Log.i(TAG, " TYPE_TEXT_VARIATION_POSTAL_ADDRESS"); 138 if (0 != (inputType & InputType.TYPE_TEXT_VARIATION_SHORT_MESSAGE)) 139 Log.i(TAG, " TYPE_TEXT_VARIATION_SHORT_MESSAGE"); 140 if (0 != (inputType & InputType.TYPE_TEXT_VARIATION_URI)) 141 Log.i(TAG, " TYPE_TEXT_VARIATION_URI"); 142 if (0 != (inputType & InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD)) 143 Log.i(TAG, " TYPE_TEXT_VARIATION_VISIBLE_PASSWORD"); 144 if (0 != (inputType & InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT)) 145 Log.i(TAG, " TYPE_TEXT_VARIATION_WEB_EDIT_TEXT"); 146 if (0 != (inputType & InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS)) 147 Log.i(TAG, " TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS"); 148 if (0 != (inputType & InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD)) 149 Log.i(TAG, " TYPE_TEXT_VARIATION_WEB_PASSWORD"); 150 Log.i(TAG, "Flags:"); 151 if (0 != (inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS)) 152 Log.i(TAG, " TYPE_TEXT_FLAG_NO_SUGGESTIONS"); 153 if (0 != (inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE)) 154 Log.i(TAG, " TYPE_TEXT_FLAG_MULTI_LINE"); 155 if (0 != (inputType & InputType.TYPE_TEXT_FLAG_IME_MULTI_LINE)) 156 Log.i(TAG, " TYPE_TEXT_FLAG_IME_MULTI_LINE"); 157 if (0 != (inputType & InputType.TYPE_TEXT_FLAG_CAP_WORDS)) 158 Log.i(TAG, " TYPE_TEXT_FLAG_CAP_WORDS"); 159 if (0 != (inputType & InputType.TYPE_TEXT_FLAG_CAP_SENTENCES)) 160 Log.i(TAG, " TYPE_TEXT_FLAG_CAP_SENTENCES"); 161 if (0 != (inputType & InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS)) 162 Log.i(TAG, " TYPE_TEXT_FLAG_CAP_CHARACTERS"); 163 if (0 != (inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT)) 164 Log.i(TAG, " TYPE_TEXT_FLAG_AUTO_CORRECT"); 165 if (0 != (inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE)) 166 Log.i(TAG, " TYPE_TEXT_FLAG_AUTO_COMPLETE"); 167 } 168 169 // Pretty print 170 @Override 171 public String toString() { 172 return "\n mInputTypeNoAutoCorrect = " + mInputTypeNoAutoCorrect 173 + "\n mIsSettingsSuggestionStripOn = " + mIsSettingsSuggestionStripOn 174 + "\n mApplicationSpecifiedCompletionOn = " + mApplicationSpecifiedCompletionOn; 175 } 176 177 public static boolean inPrivateImeOptions(String packageName, String key, 178 EditorInfo editorInfo) { 179 if (editorInfo == null) return false; 180 final String findingKey = (packageName != null) ? packageName + "." + key 181 : key; 182 return StringUtils.containsInCsv(findingKey, editorInfo.privateImeOptions); 183 } 184} 185