KeyboardId.java revision f86109ca563df283b336c62853533c54134dfc56
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
17package com.android.inputmethod.keyboard;
18
19import android.text.TextUtils;
20import android.view.inputmethod.EditorInfo;
21
22import com.android.inputmethod.compat.EditorInfoCompatUtils;
23import com.android.inputmethod.compat.InputTypeCompatUtils;
24
25import java.util.Arrays;
26import java.util.Locale;
27
28// TODO: Move to com.android.inputmethod.keyboard.internal package.
29/**
30 * Represents the parameters necessary to construct a new LatinKeyboard,
31 * which also serve as a unique identifier for each keyboard type.
32 */
33public class KeyboardId {
34    public static final int MODE_TEXT = 0;
35    public static final int MODE_URL = 1;
36    public static final int MODE_EMAIL = 2;
37    public static final int MODE_IM = 3;
38    public static final int MODE_PHONE = 4;
39    public static final int MODE_NUMBER = 5;
40
41    public static final int ELEMENT_ALPHABET = 0;
42    /* TODO: Implement alphabet variant shift keyboard.
43    public static final int ELEMENT_ALPHABET_MANUAL_TEMPORARY_SHIFT = 1;
44    public static final int ELEMENT_ALPHABET_AUTOMATIC_TEMPORARY_SHIFT = 2;
45    public static final int ELEMENT_ALPHABET_SHIFT_LOCK = 3;
46    public static final int ELEMENT_ALPHABET_SHIFT_LOCK_SHIFT = 4;
47    */
48    public static final int ELEMENT_SYMBOLS = 5;
49    public static final int ELEMENT_SYMBOLS_SHIFT = 6;
50    public static final int ELEMENT_PHONE = 7;
51    public static final int ELEMENT_PHONE_SHIFT = 8;
52    public static final int ELEMENT_NUMBER = 9;
53
54    // TODO: These constants could be private.
55    public static final int F2KEY_MODE_NONE = 0;
56    public static final int F2KEY_MODE_SETTINGS = 1;
57    public static final int F2KEY_MODE_SHORTCUT_IME = 2;
58    public static final int F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS = 3;
59
60    public final Locale mLocale;
61    public final int mOrientation;
62    public final int mWidth;
63    public final int mMode;
64    // TODO: Remove this field.
65    private final int mXmlId;
66    public final int mElementState;
67    public final boolean mNavigateAction;
68    public final boolean mPasswordInput;
69    // TODO: Clean up these booleans and modes.
70    public final boolean mHasSettingsKey;
71    public final int mF2KeyMode;
72    public final boolean mClobberSettingsKey;
73    public final boolean mShortcutKeyEnabled;
74    public final boolean mHasShortcutKey;
75    public final int mImeAction;
76
77    // TODO: Remove this field.
78    private final EditorInfo mEditorInfo;
79
80    private final int mHashCode;
81
82    // TODO: The hasSettings, f2KeyMode, and clobberSettingsKey arguments could be reduced.
83    public KeyboardId(int xmlId, int elementState, Locale locale, int orientation, int width,
84            int mode, EditorInfo editorInfo, boolean hasSettingsKey, int f2KeyMode,
85            boolean clobberSettingsKey, boolean shortcutKeyEnabled, boolean hasShortcutKey) {
86        final int inputType = (editorInfo != null) ? editorInfo.inputType : 0;
87        final int imeOptions = (editorInfo != null) ? editorInfo.imeOptions : 0;
88        this.mElementState = elementState;
89        this.mLocale = locale;
90        this.mOrientation = orientation;
91        this.mWidth = width;
92        this.mMode = mode;
93        this.mXmlId = xmlId;
94        // Note: Turn off checking navigation flag to show TAB key for now.
95        this.mNavigateAction = InputTypeCompatUtils.isWebInputType(inputType);
96//                || EditorInfoCompatUtils.hasFlagNavigateNext(imeOptions)
97//                || EditorInfoCompatUtils.hasFlagNavigatePrevious(imeOptions);
98        this.mPasswordInput = InputTypeCompatUtils.isPasswordInputType(inputType)
99                || InputTypeCompatUtils.isVisiblePasswordInputType(inputType);
100        this.mHasSettingsKey = hasSettingsKey;
101        this.mF2KeyMode = f2KeyMode;
102        this.mClobberSettingsKey = clobberSettingsKey;
103        this.mShortcutKeyEnabled = shortcutKeyEnabled;
104        this.mHasShortcutKey = hasShortcutKey;
105        // We are interested only in {@link EditorInfo#IME_MASK_ACTION} enum value and
106        // {@link EditorInfo#IME_FLAG_NO_ENTER_ACTION}.
107        this.mImeAction = imeOptions & (
108                EditorInfo.IME_MASK_ACTION | EditorInfo.IME_FLAG_NO_ENTER_ACTION);
109
110        this.mEditorInfo = editorInfo;
111
112        this.mHashCode = Arrays.hashCode(new Object[] {
113                locale,
114                orientation,
115                width,
116                mode,
117                xmlId,
118                elementState,
119                mNavigateAction,
120                mPasswordInput,
121                hasSettingsKey,
122                f2KeyMode,
123                clobberSettingsKey,
124                shortcutKeyEnabled,
125                hasShortcutKey,
126                mImeAction,
127        });
128    }
129
130    public KeyboardId cloneWithNewXml(int xmlId) {
131        return new KeyboardId(xmlId, mElementState, mLocale,
132                mOrientation, mWidth, mMode, mEditorInfo, false, F2KEY_MODE_NONE, false, false,
133                false);
134    }
135
136    // Remove this method.
137    public int getXmlId() {
138        return mXmlId;
139    }
140
141    public boolean isAlphabetKeyboard() {
142        return mElementState < ELEMENT_SYMBOLS;
143    }
144
145    public boolean isSymbolsKeyboard() {
146        return mElementState == ELEMENT_SYMBOLS || mElementState == ELEMENT_SYMBOLS_SHIFT;
147    }
148
149    public boolean isPhoneKeyboard() {
150        return mElementState == ELEMENT_PHONE || mElementState == ELEMENT_PHONE_SHIFT;
151    }
152
153    public boolean isPhoneShiftKeyboard() {
154        return mElementState == ELEMENT_PHONE_SHIFT;
155    }
156
157    @Override
158    public boolean equals(Object other) {
159        return other instanceof KeyboardId && equals((KeyboardId) other);
160    }
161
162    private boolean equals(KeyboardId other) {
163        return other.mLocale.equals(this.mLocale)
164            && other.mOrientation == this.mOrientation
165            && other.mWidth == this.mWidth
166            && other.mMode == this.mMode
167            && other.mXmlId == this.mXmlId
168            && other.mElementState == this.mElementState
169            && other.mNavigateAction == this.mNavigateAction
170            && other.mPasswordInput == this.mPasswordInput
171            && other.mHasSettingsKey == this.mHasSettingsKey
172            && other.mF2KeyMode == this.mF2KeyMode
173            && other.mClobberSettingsKey == this.mClobberSettingsKey
174            && other.mShortcutKeyEnabled == this.mShortcutKeyEnabled
175            && other.mHasShortcutKey == this.mHasShortcutKey
176            && other.mImeAction == this.mImeAction;
177    }
178
179    @Override
180    public int hashCode() {
181        return mHashCode;
182    }
183
184    @Override
185    public String toString() {
186        return String.format("[%s %s %s%d %s %s %s%s%s%s%s%s%s]",
187                elementStateToString(mElementState),
188                mLocale,
189                (mOrientation == 1 ? "port" : "land"), mWidth,
190                modeName(mMode),
191                EditorInfoCompatUtils.imeOptionsName(mImeAction),
192                f2KeyModeName(mF2KeyMode),
193                (mClobberSettingsKey ? " clobberSettingsKey" : ""),
194                (mNavigateAction ? " navigateAction" : ""),
195                (mPasswordInput ? " passwordInput" : ""),
196                (mHasSettingsKey ? " hasSettingsKey" : ""),
197                (mShortcutKeyEnabled ? " shortcutKeyEnabled" : ""),
198                (mHasShortcutKey ? " hasShortcutKey" : "")
199        );
200    }
201
202    public static boolean equivalentEditorInfoForKeyboard(EditorInfo a, EditorInfo b) {
203        if (a == null && b == null) return true;
204        if (a == null || b == null) return false;
205        return a.inputType == b.inputType
206                && a.imeOptions == b.imeOptions
207                && TextUtils.equals(a.privateImeOptions, b.privateImeOptions);
208    }
209
210    public static String elementStateToString(int elementState) {
211        switch (elementState) {
212        case ELEMENT_ALPHABET: return "alphabet";
213        /* TODO: Implement alphabet variant shift keyboard.
214        case ELEMENT_ALPHABET_MANUAL_TEMPORARY_SHIFT: return "alphabetManualTemporaryShift";
215        case ELEMENT_ALPHABET_AUTOMATIC_TEMPORARY_SHIFT: return "alphabetAutomaticTemporaryShift";
216        case ELEMENT_ALPHABET_SHIFT_LOCK: return "alphabetShiftLock";
217        case ELEMENT_ALPHABET_SHIFT_LOCK_SHIFT: return "alphabetShiftLockShift";
218        */
219        case ELEMENT_SYMBOLS: return "symbols";
220        case ELEMENT_SYMBOLS_SHIFT: return "symbolsShift";
221        case ELEMENT_PHONE: return "phone";
222        case ELEMENT_PHONE_SHIFT: return "phoneShift";
223        case ELEMENT_NUMBER: return "number";
224        default: return null;
225        }
226    }
227
228    public static String modeName(int mode) {
229        switch (mode) {
230        case MODE_TEXT: return "text";
231        case MODE_URL: return "url";
232        case MODE_EMAIL: return "email";
233        case MODE_IM: return "im";
234        case MODE_PHONE: return "phone";
235        case MODE_NUMBER: return "number";
236        default: return null;
237        }
238    }
239
240    public static String f2KeyModeName(int f2KeyMode) {
241        switch (f2KeyMode) {
242        case F2KEY_MODE_NONE: return "none";
243        case F2KEY_MODE_SETTINGS: return "settings";
244        case F2KEY_MODE_SHORTCUT_IME: return "shortcutIme";
245        case F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS: return "shortcutImeOrSettings";
246        default: return null;
247        }
248    }
249}
250