Home | History | Annotate | Download | only in latin
      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