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