1 /* 2 * Copyright (C) 2010 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 17 package com.android.inputmethod.keyboard; 18 19 import static com.android.inputmethod.latin.Constants.Subtype.ExtraValue.KEYBOARD_LAYOUT_SET; 20 21 import android.text.InputType; 22 import android.text.TextUtils; 23 import android.view.inputmethod.EditorInfo; 24 import android.view.inputmethod.InputMethodSubtype; 25 26 import com.android.inputmethod.compat.EditorInfoCompatUtils; 27 import com.android.inputmethod.latin.InputTypeUtils; 28 import com.android.inputmethod.latin.SubtypeLocale; 29 30 import java.util.Arrays; 31 import java.util.Locale; 32 33 /** 34 * Unique identifier for each keyboard type. 35 */ 36 public class KeyboardId { 37 public static final int MODE_TEXT = 0; 38 public static final int MODE_URL = 1; 39 public static final int MODE_EMAIL = 2; 40 public static final int MODE_IM = 3; 41 public static final int MODE_PHONE = 4; 42 public static final int MODE_NUMBER = 5; 43 public static final int MODE_DATE = 6; 44 public static final int MODE_TIME = 7; 45 public static final int MODE_DATETIME = 8; 46 47 public static final int ELEMENT_ALPHABET = 0; 48 public static final int ELEMENT_ALPHABET_MANUAL_SHIFTED = 1; 49 public static final int ELEMENT_ALPHABET_AUTOMATIC_SHIFTED = 2; 50 public static final int ELEMENT_ALPHABET_SHIFT_LOCKED = 3; 51 public static final int ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED = 4; 52 public static final int ELEMENT_SYMBOLS = 5; 53 public static final int ELEMENT_SYMBOLS_SHIFTED = 6; 54 public static final int ELEMENT_PHONE = 7; 55 public static final int ELEMENT_PHONE_SYMBOLS = 8; 56 public static final int ELEMENT_NUMBER = 9; 57 58 private static final int IME_ACTION_CUSTOM_LABEL = EditorInfo.IME_MASK_ACTION + 1; 59 60 public final InputMethodSubtype mSubtype; 61 public final Locale mLocale; 62 public final int mOrientation; 63 public final int mWidth; 64 public final int mMode; 65 public final int mElementId; 66 private final EditorInfo mEditorInfo; 67 public final boolean mClobberSettingsKey; 68 public final boolean mShortcutKeyEnabled; 69 public final boolean mHasShortcutKey; 70 public final boolean mLanguageSwitchKeyEnabled; 71 public final String mCustomActionLabel; 72 73 private final int mHashCode; 74 KeyboardId(int elementId, InputMethodSubtype subtype, int orientation, int width, int mode, EditorInfo editorInfo, boolean clobberSettingsKey, boolean shortcutKeyEnabled, boolean hasShortcutKey, boolean languageSwitchKeyEnabled)75 public KeyboardId(int elementId, InputMethodSubtype subtype, int orientation, int width, 76 int mode, EditorInfo editorInfo, boolean clobberSettingsKey, boolean shortcutKeyEnabled, 77 boolean hasShortcutKey, boolean languageSwitchKeyEnabled) { 78 mSubtype = subtype; 79 mLocale = SubtypeLocale.getSubtypeLocale(subtype); 80 mOrientation = orientation; 81 mWidth = width; 82 mMode = mode; 83 mElementId = elementId; 84 mEditorInfo = editorInfo; 85 mClobberSettingsKey = clobberSettingsKey; 86 mShortcutKeyEnabled = shortcutKeyEnabled; 87 mHasShortcutKey = hasShortcutKey; 88 mLanguageSwitchKeyEnabled = languageSwitchKeyEnabled; 89 mCustomActionLabel = (editorInfo.actionLabel != null) 90 ? editorInfo.actionLabel.toString() : null; 91 92 mHashCode = computeHashCode(this); 93 } 94 computeHashCode(KeyboardId id)95 private static int computeHashCode(KeyboardId id) { 96 return Arrays.hashCode(new Object[] { 97 id.mOrientation, 98 id.mElementId, 99 id.mMode, 100 id.mWidth, 101 id.passwordInput(), 102 id.mClobberSettingsKey, 103 id.mShortcutKeyEnabled, 104 id.mHasShortcutKey, 105 id.mLanguageSwitchKeyEnabled, 106 id.isMultiLine(), 107 id.imeAction(), 108 id.mCustomActionLabel, 109 id.navigateNext(), 110 id.navigatePrevious(), 111 id.mSubtype 112 }); 113 } 114 equals(KeyboardId other)115 private boolean equals(KeyboardId other) { 116 if (other == this) 117 return true; 118 return other.mOrientation == mOrientation 119 && other.mElementId == mElementId 120 && other.mMode == mMode 121 && other.mWidth == mWidth 122 && other.passwordInput() == passwordInput() 123 && other.mClobberSettingsKey == mClobberSettingsKey 124 && other.mShortcutKeyEnabled == mShortcutKeyEnabled 125 && other.mHasShortcutKey == mHasShortcutKey 126 && other.mLanguageSwitchKeyEnabled == mLanguageSwitchKeyEnabled 127 && other.isMultiLine() == isMultiLine() 128 && other.imeAction() == imeAction() 129 && TextUtils.equals(other.mCustomActionLabel, mCustomActionLabel) 130 && other.navigateNext() == navigateNext() 131 && other.navigatePrevious() == navigatePrevious() 132 && other.mSubtype.equals(mSubtype); 133 } 134 isAlphabetKeyboard()135 public boolean isAlphabetKeyboard() { 136 return mElementId < ELEMENT_SYMBOLS; 137 } 138 navigateNext()139 public boolean navigateNext() { 140 return (mEditorInfo.imeOptions & EditorInfo.IME_FLAG_NAVIGATE_NEXT) != 0; 141 } 142 navigatePrevious()143 public boolean navigatePrevious() { 144 return (mEditorInfo.imeOptions & EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS) != 0; 145 } 146 passwordInput()147 public boolean passwordInput() { 148 final int inputType = mEditorInfo.inputType; 149 return InputTypeUtils.isPasswordInputType(inputType) 150 || InputTypeUtils.isVisiblePasswordInputType(inputType); 151 } 152 isMultiLine()153 public boolean isMultiLine() { 154 return (mEditorInfo.inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) != 0; 155 } 156 imeAction()157 public int imeAction() { 158 final int actionId = mEditorInfo.imeOptions & EditorInfo.IME_MASK_ACTION; 159 if ((mEditorInfo.imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) { 160 return EditorInfo.IME_ACTION_NONE; 161 } else if (mEditorInfo.actionLabel != null) { 162 return IME_ACTION_CUSTOM_LABEL; 163 } else { 164 return actionId; 165 } 166 } 167 imeActionId()168 public int imeActionId() { 169 final int actionId = imeAction(); 170 return actionId == IME_ACTION_CUSTOM_LABEL ? mEditorInfo.actionId : actionId; 171 } 172 173 @Override equals(Object other)174 public boolean equals(Object other) { 175 return other instanceof KeyboardId && equals((KeyboardId) other); 176 } 177 178 @Override hashCode()179 public int hashCode() { 180 return mHashCode; 181 } 182 183 @Override toString()184 public String toString() { 185 return String.format("[%s %s:%s %s%d %s %s %s%s%s%s%s%s%s%s]", 186 elementIdToName(mElementId), 187 mLocale, 188 mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET), 189 (mOrientation == 1 ? "port" : "land"), mWidth, 190 modeName(mMode), 191 imeAction(), 192 (navigateNext() ? "navigateNext" : ""), 193 (navigatePrevious() ? "navigatePrevious" : ""), 194 (mClobberSettingsKey ? " clobberSettingsKey" : ""), 195 (passwordInput() ? " passwordInput" : ""), 196 (mShortcutKeyEnabled ? " shortcutKeyEnabled" : ""), 197 (mHasShortcutKey ? " hasShortcutKey" : ""), 198 (mLanguageSwitchKeyEnabled ? " languageSwitchKeyEnabled" : ""), 199 (isMultiLine() ? "isMultiLine" : "") 200 ); 201 } 202 equivalentEditorInfoForKeyboard(EditorInfo a, EditorInfo b)203 public static boolean equivalentEditorInfoForKeyboard(EditorInfo a, EditorInfo b) { 204 if (a == null && b == null) return true; 205 if (a == null || b == null) return false; 206 return a.inputType == b.inputType 207 && a.imeOptions == b.imeOptions 208 && TextUtils.equals(a.privateImeOptions, b.privateImeOptions); 209 } 210 elementIdToName(int elementId)211 public static String elementIdToName(int elementId) { 212 switch (elementId) { 213 case ELEMENT_ALPHABET: return "alphabet"; 214 case ELEMENT_ALPHABET_MANUAL_SHIFTED: return "alphabetManualShifted"; 215 case ELEMENT_ALPHABET_AUTOMATIC_SHIFTED: return "alphabetAutomaticShifted"; 216 case ELEMENT_ALPHABET_SHIFT_LOCKED: return "alphabetShiftLocked"; 217 case ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED: return "alphabetShiftLockShifted"; 218 case ELEMENT_SYMBOLS: return "symbols"; 219 case ELEMENT_SYMBOLS_SHIFTED: return "symbolsShifted"; 220 case ELEMENT_PHONE: return "phone"; 221 case ELEMENT_PHONE_SYMBOLS: return "phoneSymbols"; 222 case ELEMENT_NUMBER: return "number"; 223 default: return null; 224 } 225 } 226 modeName(int mode)227 public static String modeName(int mode) { 228 switch (mode) { 229 case MODE_TEXT: return "text"; 230 case MODE_URL: return "url"; 231 case MODE_EMAIL: return "email"; 232 case MODE_IM: return "im"; 233 case MODE_PHONE: return "phone"; 234 case MODE_NUMBER: return "number"; 235 case MODE_DATE: return "date"; 236 case MODE_TIME: return "time"; 237 case MODE_DATETIME: return "datetime"; 238 default: return null; 239 } 240 } 241 actionName(int actionId)242 public static String actionName(int actionId) { 243 return (actionId == IME_ACTION_CUSTOM_LABEL) ? "actionCustomLabel" 244 : EditorInfoCompatUtils.imeActionName(actionId); 245 } 246 } 247