• 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"); 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 final 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     public static final int FORM_FACTOR_PHONE = 0;
59     public static final int FORM_FACTOR_TABLET7 = 1;
60     public static final int FORM_FACTOR_TABLET10 = 2;
61 
62     private static final int IME_ACTION_CUSTOM_LABEL = EditorInfo.IME_MASK_ACTION + 1;
63 
64     public final InputMethodSubtype mSubtype;
65     public final Locale mLocale;
66     public final int mDeviceFormFactor;
67     public final int mOrientation;
68     public final int mWidth;
69     public final int mMode;
70     public final int mElementId;
71     private final EditorInfo mEditorInfo;
72     public final boolean mClobberSettingsKey;
73     public final boolean mShortcutKeyEnabled;
74     public final boolean mHasShortcutKey;
75     public final boolean mLanguageSwitchKeyEnabled;
76     public final String mCustomActionLabel;
77 
78     private final int mHashCode;
79 
KeyboardId(int elementId, InputMethodSubtype subtype, int deviceFormFactor, int orientation, int width, int mode, EditorInfo editorInfo, boolean clobberSettingsKey, boolean shortcutKeyEnabled, boolean hasShortcutKey, boolean languageSwitchKeyEnabled)80     public KeyboardId(int elementId, InputMethodSubtype subtype, int deviceFormFactor,
81             int orientation, int width, int mode, EditorInfo editorInfo, boolean clobberSettingsKey,
82             boolean shortcutKeyEnabled, boolean hasShortcutKey, boolean languageSwitchKeyEnabled) {
83         mSubtype = subtype;
84         mLocale = SubtypeLocale.getSubtypeLocale(subtype);
85         mDeviceFormFactor = deviceFormFactor;
86         mOrientation = orientation;
87         mWidth = width;
88         mMode = mode;
89         mElementId = elementId;
90         mEditorInfo = editorInfo;
91         mClobberSettingsKey = clobberSettingsKey;
92         mShortcutKeyEnabled = shortcutKeyEnabled;
93         mHasShortcutKey = hasShortcutKey;
94         mLanguageSwitchKeyEnabled = languageSwitchKeyEnabled;
95         mCustomActionLabel = (editorInfo.actionLabel != null)
96                 ? editorInfo.actionLabel.toString() : null;
97 
98         mHashCode = computeHashCode(this);
99     }
100 
computeHashCode(KeyboardId id)101     private static int computeHashCode(KeyboardId id) {
102         return Arrays.hashCode(new Object[] {
103                 id.mDeviceFormFactor,
104                 id.mOrientation,
105                 id.mElementId,
106                 id.mMode,
107                 id.mWidth,
108                 id.passwordInput(),
109                 id.mClobberSettingsKey,
110                 id.mShortcutKeyEnabled,
111                 id.mHasShortcutKey,
112                 id.mLanguageSwitchKeyEnabled,
113                 id.isMultiLine(),
114                 id.imeAction(),
115                 id.mCustomActionLabel,
116                 id.navigateNext(),
117                 id.navigatePrevious(),
118                 id.mSubtype
119         });
120     }
121 
equals(KeyboardId other)122     private boolean equals(KeyboardId other) {
123         if (other == this)
124             return true;
125         return other.mDeviceFormFactor == mDeviceFormFactor
126                 && other.mOrientation == mOrientation
127                 && other.mElementId == mElementId
128                 && other.mMode == mMode
129                 && other.mWidth == mWidth
130                 && other.passwordInput() == passwordInput()
131                 && other.mClobberSettingsKey == mClobberSettingsKey
132                 && other.mShortcutKeyEnabled == mShortcutKeyEnabled
133                 && other.mHasShortcutKey == mHasShortcutKey
134                 && other.mLanguageSwitchKeyEnabled == mLanguageSwitchKeyEnabled
135                 && other.isMultiLine() == isMultiLine()
136                 && other.imeAction() == imeAction()
137                 && TextUtils.equals(other.mCustomActionLabel, mCustomActionLabel)
138                 && other.navigateNext() == navigateNext()
139                 && other.navigatePrevious() == navigatePrevious()
140                 && other.mSubtype.equals(mSubtype);
141     }
142 
isAlphabetKeyboard()143     public boolean isAlphabetKeyboard() {
144         return mElementId < ELEMENT_SYMBOLS;
145     }
146 
navigateNext()147     public boolean navigateNext() {
148         return (mEditorInfo.imeOptions & EditorInfo.IME_FLAG_NAVIGATE_NEXT) != 0
149                 || imeAction() == EditorInfo.IME_ACTION_NEXT;
150     }
151 
navigatePrevious()152     public boolean navigatePrevious() {
153         return (mEditorInfo.imeOptions & EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS) != 0
154                 || imeAction() == EditorInfo.IME_ACTION_PREVIOUS;
155     }
156 
passwordInput()157     public boolean passwordInput() {
158         final int inputType = mEditorInfo.inputType;
159         return InputTypeUtils.isPasswordInputType(inputType)
160                 || InputTypeUtils.isVisiblePasswordInputType(inputType);
161     }
162 
isMultiLine()163     public boolean isMultiLine() {
164         return (mEditorInfo.inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) != 0;
165     }
166 
imeAction()167     public int imeAction() {
168         final int actionId = mEditorInfo.imeOptions & EditorInfo.IME_MASK_ACTION;
169         if ((mEditorInfo.imeOptions & EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
170             return EditorInfo.IME_ACTION_NONE;
171         } else if (mEditorInfo.actionLabel != null) {
172             return IME_ACTION_CUSTOM_LABEL;
173         } else {
174             return actionId;
175         }
176     }
177 
imeActionId()178     public int imeActionId() {
179         final int actionId = imeAction();
180         return actionId == IME_ACTION_CUSTOM_LABEL ? mEditorInfo.actionId : actionId;
181     }
182 
183     @Override
equals(Object other)184     public boolean equals(Object other) {
185         return other instanceof KeyboardId && equals((KeyboardId) other);
186     }
187 
188     @Override
hashCode()189     public int hashCode() {
190         return mHashCode;
191     }
192 
193     @Override
toString()194     public String toString() {
195         return String.format("[%s %s:%s %s-%s:%d %s %s %s%s%s%s%s%s%s%s]",
196                 elementIdToName(mElementId),
197                 mLocale,
198                 mSubtype.getExtraValueOf(KEYBOARD_LAYOUT_SET),
199                 deviceFormFactor(mDeviceFormFactor), (mOrientation == 1 ? "port" : "land"), mWidth,
200                 modeName(mMode),
201                 imeAction(),
202                 (navigateNext() ? "navigateNext" : ""),
203                 (navigatePrevious() ? "navigatePrevious" : ""),
204                 (mClobberSettingsKey ? " clobberSettingsKey" : ""),
205                 (passwordInput() ? " passwordInput" : ""),
206                 (mShortcutKeyEnabled ? " shortcutKeyEnabled" : ""),
207                 (mHasShortcutKey ? " hasShortcutKey" : ""),
208                 (mLanguageSwitchKeyEnabled ? " languageSwitchKeyEnabled" : ""),
209                 (isMultiLine() ? "isMultiLine" : "")
210         );
211     }
212 
equivalentEditorInfoForKeyboard(EditorInfo a, EditorInfo b)213     public static boolean equivalentEditorInfoForKeyboard(EditorInfo a, EditorInfo b) {
214         if (a == null && b == null) return true;
215         if (a == null || b == null) return false;
216         return a.inputType == b.inputType
217                 && a.imeOptions == b.imeOptions
218                 && TextUtils.equals(a.privateImeOptions, b.privateImeOptions);
219     }
220 
elementIdToName(int elementId)221     public static String elementIdToName(int elementId) {
222         switch (elementId) {
223         case ELEMENT_ALPHABET: return "alphabet";
224         case ELEMENT_ALPHABET_MANUAL_SHIFTED: return "alphabetManualShifted";
225         case ELEMENT_ALPHABET_AUTOMATIC_SHIFTED: return "alphabetAutomaticShifted";
226         case ELEMENT_ALPHABET_SHIFT_LOCKED: return "alphabetShiftLocked";
227         case ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED: return "alphabetShiftLockShifted";
228         case ELEMENT_SYMBOLS: return "symbols";
229         case ELEMENT_SYMBOLS_SHIFTED: return "symbolsShifted";
230         case ELEMENT_PHONE: return "phone";
231         case ELEMENT_PHONE_SYMBOLS: return "phoneSymbols";
232         case ELEMENT_NUMBER: return "number";
233         default: return null;
234         }
235     }
236 
deviceFormFactor(int devoceFormFactor)237     public static String deviceFormFactor(int devoceFormFactor) {
238         switch (devoceFormFactor) {
239         case FORM_FACTOR_PHONE: return "phone";
240         case FORM_FACTOR_TABLET7: return "tablet7";
241         case FORM_FACTOR_TABLET10: return "tablet10";
242         default: return null;
243         }
244     }
245 
modeName(int mode)246     public static String modeName(int mode) {
247         switch (mode) {
248         case MODE_TEXT: return "text";
249         case MODE_URL: return "url";
250         case MODE_EMAIL: return "email";
251         case MODE_IM: return "im";
252         case MODE_PHONE: return "phone";
253         case MODE_NUMBER: return "number";
254         case MODE_DATE: return "date";
255         case MODE_TIME: return "time";
256         case MODE_DATETIME: return "datetime";
257         default: return null;
258         }
259     }
260 
actionName(int actionId)261     public static String actionName(int actionId) {
262         return (actionId == IME_ACTION_CUSTOM_LABEL) ? "actionCustomLabel"
263                 : EditorInfoCompatUtils.imeActionName(actionId);
264     }
265 }
266