KeyboardSwitcher.java revision 889691eca1ad991a85fb721deb37ecba6a913762
1923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/* 2443c360d0afdbab091994244f045f4756feaf2b4Jean-Baptiste Queru * Copyright (C) 2008 The Android Open Source Project 3923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * 4923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * use this file except in compliance with the License. You may obtain a copy of 6923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * the License at 7923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * 8923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * 10923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * License for the specific language governing permissions and limitations under 14923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * the License. 15923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 16923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 17923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectpackage com.android.inputmethod.latin; 18923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 198b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaokaimport android.content.Context; 20979f8690967ff5409fe18f5085858ccdb8e0ccf1satokimport android.content.SharedPreferences; 2136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.content.res.Configuration; 2236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.content.res.Resources; 23979f8690967ff5409fe18f5085858ccdb8e0ccf1satokimport android.preference.PreferenceManager; 248b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaokaimport android.util.Log; 25979f8690967ff5409fe18f5085858ccdb8e0ccf1satokimport android.view.InflateException; 2636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 27681b676b0aecb30e644f25550018ce2b6cea3e15Tadashi G. Takaokaimport java.lang.ref.SoftReference; 287e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaokaimport java.util.Arrays; 2912659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaokaimport java.util.HashMap; 3012659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaokaimport java.util.Locale; 3112659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaoka 32979f8690967ff5409fe18f5085858ccdb8e0ccf1satokpublic class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceChangeListener { 338b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private static final String TAG = "KeyboardSwitcher"; 348b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private static final boolean DEBUG = false; 35923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 36e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa public static final int MODE_TEXT = 0; 37e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa public static final int MODE_URL = 1; 38e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa public static final int MODE_EMAIL = 2; 39e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa public static final int MODE_IM = 3; 40e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa public static final int MODE_WEB = 4; 41e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa public static final int MODE_PHONE = 5; 42e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa 4331adfa78e2edae188edb05e869f9f68798857582satok public static final String DEFAULT_LAYOUT_ID = "4"; 44a327485e595c9f7676989097c830ff452085d4c9satok public static final String PREF_KEYBOARD_LAYOUT = "pref_keyboard_layout_20100902"; 45979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private static final int[] THEMES = new int [] { 46979f8690967ff5409fe18f5085858ccdb8e0ccf1satok R.layout.input_basic, R.layout.input_basic_highcontrast, R.layout.input_stone_normal, 4731adfa78e2edae188edb05e869f9f68798857582satok R.layout.input_stone_bold, R.layout.input_gingerbread}; 48979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 49979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Ids for each characters' color in the keyboard 50979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private static final int CHAR_THEME_COLOR_WHITE = 0; 51979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private static final int CHAR_THEME_COLOR_BLACK = 1; 52979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 53979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Tables which contains resource ids for each character theme color 54b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka private static final int[] KBD_PHONE = new int[] { 55b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka R.xml.kbd_phone, R.xml.kbd_phone_black 56b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka }; 57979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private static final int[] KBD_PHONE_SYMBOLS = new int[] { 58b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka R.xml.kbd_phone_symbols, R.xml.kbd_phone_symbols_black 59b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka }; 60979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private static final int[] KBD_SYMBOLS = new int[] { 61b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka R.xml.kbd_symbols, R.xml.kbd_symbols_black 62b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka }; 63979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private static final int[] KBD_SYMBOLS_SHIFT = new int[] { 64b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka R.xml.kbd_symbols_shift, R.xml.kbd_symbols_shift_black 65b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka }; 66b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka private static final int[] KBD_QWERTY = new int[] { 67b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka R.xml.kbd_qwerty, R.xml.kbd_qwerty_black 68b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka }; 69979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 70b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani private static final int SYMBOLS_MODE_STATE_NONE = 0; 71b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani private static final int SYMBOLS_MODE_STATE_BEGIN = 1; 72b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani private static final int SYMBOLS_MODE_STATE_SYMBOL = 2; 73b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani 743a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka private LatinKeyboardView mInputView; 753a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka private final LatinIME mInputMethodService; 768b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private final LanguageSwitcher mLanguageSwitcher; 7731adfa78e2edae188edb05e869f9f68798857582satok 78889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka private ShiftKeyState mShiftState = new ShiftKeyState(); 796c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka private ModifierKeyState mSymbolKeyState = new ModifierKeyState(); 80889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 81353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger private KeyboardId mSymbolsId; 82353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger private KeyboardId mSymbolsShiftedId; 83353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 84353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger private KeyboardId mCurrentId; 858b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private final HashMap<KeyboardId, SoftReference<LatinKeyboard>> mKeyboardCache = 868b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka new HashMap<KeyboardId, SoftReference<LatinKeyboard>>(); 87466741d8a78965b8509bf527344f289e50873092Mike LeBeau 888b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private int mMode = MODE_TEXT; /* default value */ 89923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mImeOptions; 90353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger private boolean mIsSymbols; 9141feaaadb758a8b31d3e436063b4b5faed104d4dsatok /** mIsAutoCompletionActive indicates that auto completed word will be input instead of 9241feaaadb758a8b31d3e436063b4b5faed104d4dsatok * what user actually typed. */ 9341feaaadb758a8b31d3e436063b4b5faed104d4dsatok private boolean mIsAutoCompletionActive; 94507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka private boolean mVoiceButtonEnabled; 95507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka private boolean mVoiceButtonOnPrimary; 96b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani private int mSymbolsModeState = SYMBOLS_MODE_STATE_NONE; 97923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 981508c0e84f0cd93ab6f5d46fea5026e833f299bcKen Wakasa // Indicates whether or not we have the settings key 993a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka private boolean mHasSettingsKey; 1001508c0e84f0cd93ab6f5d46fea5026e833f299bcKen Wakasa private static final int SETTINGS_KEY_MODE_AUTO = R.string.settings_key_mode_auto; 101503797ae0e55c74068470d237fb47c4da13ec4fbTadashi G. Takaoka private static final int SETTINGS_KEY_MODE_ALWAYS_SHOW = 102503797ae0e55c74068470d237fb47c4da13ec4fbTadashi G. Takaoka R.string.settings_key_mode_always_show; 10317fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa // NOTE: No need to have SETTINGS_KEY_MODE_ALWAYS_HIDE here because it's not being referred to 10417fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa // in the source code now. 10517fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa // Default is SETTINGS_KEY_MODE_AUTO. 10617fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa private static final int DEFAULT_SETTINGS_KEY_MODE = SETTINGS_KEY_MODE_AUTO; 1071508c0e84f0cd93ab6f5d46fea5026e833f299bcKen Wakasa 108979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private int mLayoutId; 109979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1108b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka public KeyboardSwitcher(LatinIME ims, LanguageSwitcher languageSwitcher) { 1111508c0e84f0cd93ab6f5d46fea5026e833f299bcKen Wakasa mInputMethodService = ims; 1128b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mLanguageSwitcher = languageSwitcher; 113979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 114979f8690967ff5409fe18f5085858ccdb8e0ccf1satok final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ims); 115979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mLayoutId = Integer.valueOf(prefs.getString(PREF_KEYBOARD_LAYOUT, DEFAULT_LAYOUT_ID)); 116979f8690967ff5409fe18f5085858ccdb8e0ccf1satok prefs.registerOnSharedPreferenceChangeListener(this); 117979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 118979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 119e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa private void makeSymbolsKeyboardIds() { 1208b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final Locale locale = mLanguageSwitcher.getInputLocale(); 1218b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final int orientation = mInputMethodService.getResources().getConfiguration().orientation; 1228b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final int mode = mMode; 1238b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final int colorScheme = getCharColorId(); 1248b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final boolean hasSettingsKey = mHasSettingsKey; 1258b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final boolean hasVoiceKey = mVoiceButtonEnabled && !mVoiceButtonOnPrimary; 1268b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final int imeOptions = mImeOptions; 127b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka mSymbolsId = new KeyboardId(locale, orientation, mode, 1288b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka KBD_SYMBOLS, colorScheme, hasSettingsKey, hasVoiceKey, imeOptions, true); 129b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka mSymbolsShiftedId = new KeyboardId(locale, orientation, mode, 1308b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka KBD_SYMBOLS_SHIFT, colorScheme, hasSettingsKey, hasVoiceKey, imeOptions, true); 131353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 132353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 133353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger /** 134353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger * Represents the parameters necessary to construct a new LatinKeyboard, 135353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger * which also serve as a unique identifier for each keyboard type. 136353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger */ 137b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka public static class KeyboardId { 13848bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka public final Locale mLocale; 13948bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka public final int mOrientation; 14048bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka public final int mMode; 14148bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka public final int[] mXmlArray; 14248bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka public final int mColorScheme; 1438b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka public final boolean mHasSettingsKey; 1448b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka public final boolean mHasVoiceKey; 1458b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka public final int mImeOptions; 14648bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka public final boolean mEnableShiftLock; 147353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 1487e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka private final int mHashCode; 1497e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka 150b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka public KeyboardId(Locale locale, int orientation, int mode, 1518b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka int[] xmlArray, int colorScheme, boolean hasSettingsKey, boolean hasVoiceKey, 1528b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka int imeOptions, boolean enableShiftLock) { 15348bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka this.mLocale = locale; 15448bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka this.mOrientation = orientation; 15548bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka this.mMode = mode; 15648bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka this.mXmlArray = xmlArray; 15748bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka this.mColorScheme = colorScheme; 1588b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka this.mHasSettingsKey = hasSettingsKey; 1598b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka this.mHasVoiceKey = hasVoiceKey; 1608b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka this.mImeOptions = imeOptions; 16148bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka this.mEnableShiftLock = enableShiftLock; 1627e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka 1637e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka this.mHashCode = Arrays.hashCode(new Object[] { 1648b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka locale, 1658b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka orientation, 1668b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mode, 1678b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka xmlArray, 1688b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka colorScheme, 1698b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka hasSettingsKey, 1708b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka hasVoiceKey, 1718b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka imeOptions, 1728b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka enableShiftLock, 1737e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka }); 174353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 175353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 176b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka public int getXmlId() { 177b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka return mXmlArray[mColorScheme]; 178b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka } 179b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka 180b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka public boolean isAlphabetMode() { 181b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka return mXmlArray == KBD_QWERTY; 182b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka } 183b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka 184979f8690967ff5409fe18f5085858ccdb8e0ccf1satok @Override 185353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger public boolean equals(Object other) { 186353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger return other instanceof KeyboardId && equals((KeyboardId) other); 187353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 188353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 189681b676b0aecb30e644f25550018ce2b6cea3e15Tadashi G. Takaoka private boolean equals(KeyboardId other) { 19048bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka return other.mLocale.equals(this.mLocale) 19148bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka && other.mOrientation == this.mOrientation 19248bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka && other.mMode == this.mMode 19348bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka && other.mXmlArray == this.mXmlArray 19448bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka && other.mColorScheme == this.mColorScheme 1958b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka && other.mHasSettingsKey == this.mHasSettingsKey 1968b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka && other.mHasVoiceKey == this.mHasVoiceKey 1978b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka && other.mImeOptions == this.mImeOptions 19848bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka && other.mEnableShiftLock == this.mEnableShiftLock; 199353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 200353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 201979f8690967ff5409fe18f5085858ccdb8e0ccf1satok @Override 202353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger public int hashCode() { 2037e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka return mHashCode; 204923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2058b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka 2068b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka @Override 2078b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka public String toString() { 208b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka return String.format("[%s %s %5s imeOptions=0x%08x xml=0x%08x %s%s%s%s]", 209b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka mLocale, 210b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka (mOrientation == 1 ? "port" : "land"), 211b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka modeName(mMode), 212b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka mImeOptions, 213b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka mXmlArray[0], 214b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka (mColorScheme == CHAR_THEME_COLOR_WHITE ? "white" : "black"), 215b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka (mHasSettingsKey ? " hasSettingsKey" : ""), 216b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka (mHasVoiceKey ? " hasVoiceKey" : ""), 217b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka (mEnableShiftLock ? " enableShiftLock" : "")); 2188b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka } 2198b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka 2208b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private static String modeName(int mode) { 221b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka switch (mode) { 222b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka case MODE_TEXT: return "text"; 223b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka case MODE_URL: return "url"; 224b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka case MODE_EMAIL: return "email"; 225b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka case MODE_IM: return "im"; 226b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka case MODE_WEB: return "web"; 227b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka case MODE_PHONE: return "phone"; 2288b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka } 2298b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka return null; 2308b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka } 231923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 232923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2338b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private boolean hasVoiceKey(boolean isSymbols) { 234507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka return mVoiceButtonEnabled && (isSymbols != mVoiceButtonOnPrimary); 235466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 236466741d8a78965b8509bf527344f289e50873092Mike LeBeau 2378b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka public void loadKeyboard(int mode, int imeOptions, boolean voiceButtonEnabled, 238507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka boolean voiceButtonOnPrimary) { 239e3803800c53cc813e27dd1e7c31bdb4d075f0252Amith Yamasani mSymbolsModeState = SYMBOLS_MODE_STATE_NONE; 240979f8690967ff5409fe18f5085858ccdb8e0ccf1satok try { 2418b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka loadKeyboardInternal(mode, imeOptions, voiceButtonEnabled, voiceButtonOnPrimary, 242507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka false); 243979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } catch (RuntimeException e) { 244b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka Log.w(TAG, e); 245e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa LatinImeLogger.logOnException(mode + "," + imeOptions, e); 246979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 247353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 248353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 2498b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private void loadKeyboardInternal(int mode, int imeOptions, boolean voiceButtonEnabled, 250507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka boolean voiceButtonOnPrimary, boolean isSymbols) { 2516516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani if (mInputView == null) return; 2528b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mInputView.setPreviewEnabled(mInputMethodService.getPopupOn()); 2538b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka 254923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mMode = mode; 255923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mImeOptions = imeOptions; 2568b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mVoiceButtonEnabled = voiceButtonEnabled; 2578b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mVoiceButtonOnPrimary = voiceButtonOnPrimary; 258c5bb4591b67b165f007e29bd9424d319ac3c7c28Brandon Ballinger mIsSymbols = isSymbols; 2598b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka // Update the settings key state because number of enabled IMEs could have been changed 2608b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mHasSettingsKey = getSettingsKeyMode( 2618b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka PreferenceManager.getDefaultSharedPreferences(mInputMethodService), 2628b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mInputMethodService); 2638b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka makeSymbolsKeyboardIds(); 264466741d8a78965b8509bf527344f289e50873092Mike LeBeau 265353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger KeyboardId id = getKeyboardId(mode, imeOptions, isSymbols); 2668b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka LatinKeyboard keyboard = getKeyboard(id); 267353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 268353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger if (mode == MODE_PHONE) { 269353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger mInputView.setPhoneKeyboard(keyboard); 270353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 271353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 272353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger mCurrentId = id; 273353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger mInputView.setKeyboard(keyboard); 274353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 275353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 276353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger private LatinKeyboard getKeyboard(KeyboardId id) { 2778b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final SoftReference<LatinKeyboard> ref = mKeyboardCache.get(id); 278681b676b0aecb30e644f25550018ce2b6cea3e15Tadashi G. Takaoka LatinKeyboard keyboard = (ref == null) ? null : ref.get(); 279681b676b0aecb30e644f25550018ce2b6cea3e15Tadashi G. Takaoka if (keyboard == null) { 2808b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final Resources res = mInputMethodService.getResources(); 2818b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final Configuration conf = res.getConfiguration(); 2828b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final Locale saveLocale = conf.locale; 2838b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka conf.locale = mLanguageSwitcher.getInputLocale(); 28448bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka res.updateConfiguration(conf, null); 2858b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka 286b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka final int xml = id.getXmlId(); 287b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka keyboard = new LatinKeyboard(mInputMethodService, id); 2888b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka keyboard.setVoiceMode( 2898b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka hasVoiceKey(xml == R.xml.kbd_symbols || xml == R.xml.kbd_symbols_black), 2908b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mVoiceButtonEnabled); 2918b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka keyboard.setLanguageSwitcher(mLanguageSwitcher); 2928b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka keyboard.setImeOptions(res, id.mMode, id.mImeOptions); 2938b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka keyboard.setColorOfSymbolIcons(isBlackSym(id.mColorScheme)); 294358e485b14938fbcb5af5be75aa29f2b73674100Amith Yamasani 295353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger if (id.mEnableShiftLock) { 296353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger keyboard.enableShiftLock(); 297353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 2988b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka 2998b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mKeyboardCache.put(id, new SoftReference<LatinKeyboard>(keyboard)); 3008b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka if (DEBUG) 3018b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": " 3028b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka + ((ref == null) ? "LOAD" : "GCed") + " id=" + id); 30336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 30436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani conf.locale = saveLocale; 30548bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka res.updateConfiguration(conf, null); 3068b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka } else if (DEBUG) { 3078b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": HIT id=" + id); 308353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 3098b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka 3108b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka keyboard.onAutoCompletionStateChanged(mIsAutoCompletionActive); 3118b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka keyboard.setShifted(false); 312681b676b0aecb30e644f25550018ce2b6cea3e15Tadashi G. Takaoka return keyboard; 313353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 314353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 315353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger private KeyboardId getKeyboardId(int mode, int imeOptions, boolean isSymbols) { 3168b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final boolean hasVoiceKey = hasVoiceKey(isSymbols); 317e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa final int charColorId = getCharColorId(); 31848bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka final int[] xmlArray; 319e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa final boolean enableShiftLock; 320e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa 321e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa if (isSymbols) { 32248bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka xmlArray = mode == MODE_PHONE ? KBD_PHONE_SYMBOLS : KBD_SYMBOLS; 323e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa enableShiftLock = false; 324e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa } else { // QWERTY 32548bc6b158bb2890c1e5cbfe63e93705476ce9673Tadashi G. Takaoka xmlArray = mode == MODE_PHONE ? KBD_PHONE : KBD_QWERTY; 326e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa enableShiftLock = mode == MODE_PHONE ? false : true; 327923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 3288b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final int orientation = mInputMethodService.getResources().getConfiguration().orientation; 3298b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final Locale locale = mLanguageSwitcher.getInputLocale(); 330b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka return new KeyboardId(locale, orientation, mode, xmlArray, 3318b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka charColorId, mHasSettingsKey, hasVoiceKey, imeOptions, enableShiftLock); 332923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 333923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 3343a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka public int getKeyboardMode() { 335923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return mMode; 336923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 3371679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 3383a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka public boolean isAlphabetMode() { 339b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka return mCurrentId != null && mCurrentId.isAlphabetMode(); 340923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 341923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 3421679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka public boolean isInputViewShown() { 3431679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka return mInputView != null && mInputView.isShown(); 3441679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka } 3451679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 3461679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka public boolean isKeyboardAvailable() { 3471679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka return mInputView != null && mInputView.getLatinKeyboard() != null; 3481679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka } 3491679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 3501679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka public void setPreferredLetters(int[] frequencies) { 3511679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka LatinKeyboard latinKeyboard; 3521679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka if (mInputView != null && (latinKeyboard = mInputView.getLatinKeyboard()) != null) 3531679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka latinKeyboard.setPreferredLetters(frequencies); 3541679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka } 3551679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 3561679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka public void keyReleased() { 3571679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka LatinKeyboard latinKeyboard; 3581679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka if (mInputView != null && (latinKeyboard = mInputView.getLatinKeyboard()) != null) 3591679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka latinKeyboard.keyReleased(); 3601679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka } 3611679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 3621679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka public boolean isShifted() { 3631679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka LatinKeyboard latinKeyboard; 3641679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka return mInputView != null && (latinKeyboard = mInputView.getLatinKeyboard()) != null 3651679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka && latinKeyboard.isShifted(); 3661679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka } 3671679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 3681679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka public boolean isShiftLocked() { 3691679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka LatinKeyboard latinKeyboard; 3701679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka return mInputView != null && (latinKeyboard = mInputView.getLatinKeyboard()) != null 3711679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka && latinKeyboard.isShiftLocked(); 3721679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka } 3731679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 3743a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka public void setShifted(boolean shifted) { 375276845c7a9ea90fd34289d060873c8e3a7ed342cKen Wakasa if (mInputView == null) return; 376276845c7a9ea90fd34289d060873c8e3a7ed342cKen Wakasa LatinKeyboard latinKeyboard = mInputView.getLatinKeyboard(); 377276845c7a9ea90fd34289d060873c8e3a7ed342cKen Wakasa if (latinKeyboard == null) return; 378276845c7a9ea90fd34289d060873c8e3a7ed342cKen Wakasa if (latinKeyboard.setShifted(shifted)) { 379276845c7a9ea90fd34289d060873c8e3a7ed342cKen Wakasa mInputView.invalidateAllKeys(); 380979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 381979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 382979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 3833a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka public void setShiftLocked(boolean shiftLocked) { 384276845c7a9ea90fd34289d060873c8e3a7ed342cKen Wakasa if (mInputView == null) return; 385276845c7a9ea90fd34289d060873c8e3a7ed342cKen Wakasa mInputView.setShiftLocked(shiftLocked); 386979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 387979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 388889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka public void onPressShift() { 389889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka mShiftState.onPress(); 390889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka } 391889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 392889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka public void onPressShiftOnShifted() { 393889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka mShiftState.onPressOnShifted(); 394889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka } 395889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 396889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka public void onReleaseShift() { 397889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka mShiftState.onRelease(); 398889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka } 399889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 400889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka public boolean isShiftMomentary() { 401889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka return mShiftState.isMomentary(); 402889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka } 403889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 404889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka public boolean isShiftPressingOnShifted() { 405889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka return mShiftState.isPressingOnShifted(); 406889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka } 407889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 408889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka public boolean isShiftIgnoring() { 409889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka return mShiftState.isIgnoring(); 410889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka } 411889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 4126c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka public void onPressSymbol() { 4136c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka mSymbolKeyState.onPress(); 4146c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka } 4156c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka 4166c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka public void onReleaseSymbol() { 4176c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka mSymbolKeyState.onRelease(); 4186c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka } 4196c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka 4206c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka public boolean isSymbolMomentary() { 4216c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka return mSymbolKeyState.isMomentary(); 4226c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka } 4236c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka 4246c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka public void onOtherKeyPressed() { 425889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka mShiftState.onOtherKeyPressed(); 4266c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka mSymbolKeyState.onOtherKeyPressed(); 4276c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka } 4286c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka 4293a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka public void toggleShift() { 4307e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka if (isAlphabetMode()) 4317e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka return; 4328b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final LatinKeyboard keyboard; 4337e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka if (mCurrentId.equals(mSymbolsId) || !mCurrentId.equals(mSymbolsShiftedId)) { 434353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger mCurrentId = mSymbolsShiftedId; 4358b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka keyboard = getKeyboard(mCurrentId); 43612659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaoka // Symbol shifted keyboard has an ALT key that has a caps lock style indicator. To 43712659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaoka // enable the indicator, we need to call enableShiftLock() and setShiftLocked(true). 43812659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaoka // Thus we can keep the ALT key's Key.on value true while LatinKey.onRelease() is 43912659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaoka // called. 4408b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka keyboard.setShiftLocked(true); 4417e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka } else { 442353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger mCurrentId = mSymbolsId; 4438b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka keyboard = getKeyboard(mCurrentId); 44412659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaoka // Symbol keyboard has an ALT key that has a caps lock style indicator. To disable the 44512659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaoka // indicator, we need to call enableShiftLock() and setShiftLocked(false). 4468b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka keyboard.setShifted(false); 447923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 4488b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mInputView.setKeyboard(keyboard); 449923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 450923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 4513a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka public void toggleSymbols() { 4528b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka loadKeyboardInternal(mMode, mImeOptions, mVoiceButtonEnabled, mVoiceButtonOnPrimary, 453507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka !mIsSymbols); 454e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa if (mIsSymbols) { 455b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani mSymbolsModeState = SYMBOLS_MODE_STATE_BEGIN; 456b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani } else { 457b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani mSymbolsModeState = SYMBOLS_MODE_STATE_NONE; 458b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani } 459b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani } 460b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani 461c8b9afe0378e3f33c3f83271bd1df9678a70c2a2Tadashi G. Takaoka public boolean hasDistinctMultitouch() { 462c8b9afe0378e3f33c3f83271bd1df9678a70c2a2Tadashi G. Takaoka return mInputView != null && mInputView.hasDistinctMultitouch(); 463c8b9afe0378e3f33c3f83271bd1df9678a70c2a2Tadashi G. Takaoka } 464c8b9afe0378e3f33c3f83271bd1df9678a70c2a2Tadashi G. Takaoka 465b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani /** 466b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani * Updates state machine to figure out when to automatically switch back to alpha mode. 467b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani * Returns true if the keyboard needs to switch back 468b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani */ 4693a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka public boolean onKey(int key) { 470d67fe0e7583f1be18b35b33b7658e4427f1e3dedAmith Yamasani // Switch back to alpha mode if user types one or more non-space/enter characters 471d67fe0e7583f1be18b35b33b7658e4427f1e3dedAmith Yamasani // followed by a space/enter 472b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani switch (mSymbolsModeState) { 473b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani case SYMBOLS_MODE_STATE_BEGIN: 474d67fe0e7583f1be18b35b33b7658e4427f1e3dedAmith Yamasani if (key != LatinIME.KEYCODE_SPACE && key != LatinIME.KEYCODE_ENTER && key > 0) { 475d67fe0e7583f1be18b35b33b7658e4427f1e3dedAmith Yamasani mSymbolsModeState = SYMBOLS_MODE_STATE_SYMBOL; 476d67fe0e7583f1be18b35b33b7658e4427f1e3dedAmith Yamasani } 477b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani break; 478b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani case SYMBOLS_MODE_STATE_SYMBOL: 479d67fe0e7583f1be18b35b33b7658e4427f1e3dedAmith Yamasani if (key == LatinIME.KEYCODE_ENTER || key == LatinIME.KEYCODE_SPACE) return true; 480b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani break; 481b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani } 482b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani return false; 483923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 484979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 485979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public LatinKeyboardView getInputView() { 486979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return mInputView; 487979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 488979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 4898b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka public void loadKeyboardView() { 4908b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka loadKeyboardViewInternal(mLayoutId, true); 491979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 492979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 4938b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private void loadKeyboardViewInternal(int newLayout, boolean forceReset) { 494979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mLayoutId != newLayout || mInputView == null || forceReset) { 495979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mInputView != null) { 496979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mInputView.closing(); 497979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 498979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (THEMES.length <= newLayout) { 499979f8690967ff5409fe18f5085858ccdb8e0ccf1satok newLayout = Integer.valueOf(DEFAULT_LAYOUT_ID); 500979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 501979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 502979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinIMEUtil.GCUtils.getInstance().reset(); 503979f8690967ff5409fe18f5085858ccdb8e0ccf1satok boolean tryGC = true; 504979f8690967ff5409fe18f5085858ccdb8e0ccf1satok for (int i = 0; i < LatinIMEUtil.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) { 505979f8690967ff5409fe18f5085858ccdb8e0ccf1satok try { 506979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mInputView = (LatinKeyboardView) mInputMethodService.getLayoutInflater( 507979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ).inflate(THEMES[newLayout], null); 508979f8690967ff5409fe18f5085858ccdb8e0ccf1satok tryGC = false; 509979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } catch (OutOfMemoryError e) { 510979f8690967ff5409fe18f5085858ccdb8e0ccf1satok tryGC = LatinIMEUtil.GCUtils.getInstance().tryGCOrWait( 511979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mLayoutId + "," + newLayout, e); 512979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } catch (InflateException e) { 513979f8690967ff5409fe18f5085858ccdb8e0ccf1satok tryGC = LatinIMEUtil.GCUtils.getInstance().tryGCOrWait( 514979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mLayoutId + "," + newLayout, e); 515979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 516979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 517979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mInputView.setOnKeyboardActionListener(mInputMethodService); 518979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mLayoutId = newLayout; 519979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 520979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mInputMethodService.mHandler.post(new Runnable() { 521979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public void run() { 522979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mInputView != null) { 523979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mInputMethodService.setInputView(mInputView); 524979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 525979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mInputMethodService.updateInputViewShown(); 526979f8690967ff5409fe18f5085858ccdb8e0ccf1satok }}); 527979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 528979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 529979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 530979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (PREF_KEYBOARD_LAYOUT.equals(key)) { 5318b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final int layoutId = Integer.valueOf( 5328b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka sharedPreferences.getString(key, DEFAULT_LAYOUT_ID)); 5338b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka loadKeyboardViewInternal(layoutId, false); 5341508c0e84f0cd93ab6f5d46fea5026e833f299bcKen Wakasa } else if (LatinIMESettings.PREF_SETTINGS_KEY.equals(key)) { 5358b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mHasSettingsKey = getSettingsKeyMode(sharedPreferences, mInputMethodService); 5368b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka loadKeyboardViewInternal(mLayoutId, true); 537979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 538979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 539979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 5408b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka public boolean isBlackSym() { 5411508c0e84f0cd93ab6f5d46fea5026e833f299bcKen Wakasa if (mInputView != null && mInputView.getSymbolColorScheme() == 1) { 542979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return true; 543979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 544979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return false; 545979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 546979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 5478b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private boolean isBlackSym(int colorScheme) { 5488b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka return colorScheme == CHAR_THEME_COLOR_BLACK; 5498b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka } 5508b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka 5518b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private int getCharColorId() { 552979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (isBlackSym()) { 553979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return CHAR_THEME_COLOR_BLACK; 554979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } else { 555979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return CHAR_THEME_COLOR_WHITE; 556979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 557979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 558979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 55941feaaadb758a8b31d3e436063b4b5faed104d4dsatok public void onAutoCompletionStateChanged(boolean isAutoCompletion) { 56041feaaadb758a8b31d3e436063b4b5faed104d4dsatok if (isAutoCompletion != mIsAutoCompletionActive) { 56141feaaadb758a8b31d3e436063b4b5faed104d4dsatok LatinKeyboardView keyboardView = getInputView(); 56241feaaadb758a8b31d3e436063b4b5faed104d4dsatok mIsAutoCompletionActive = isAutoCompletion; 56341feaaadb758a8b31d3e436063b4b5faed104d4dsatok keyboardView.invalidateKey(((LatinKeyboard) keyboardView.getKeyboard()) 56441feaaadb758a8b31d3e436063b4b5faed104d4dsatok .onAutoCompletionStateChanged(isAutoCompletion)); 56541feaaadb758a8b31d3e436063b4b5faed104d4dsatok } 56641feaaadb758a8b31d3e436063b4b5faed104d4dsatok } 5671508c0e84f0cd93ab6f5d46fea5026e833f299bcKen Wakasa 5688b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private static boolean getSettingsKeyMode(SharedPreferences prefs, Context context) { 5698b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka Resources resources = context.getResources(); 570503797ae0e55c74068470d237fb47c4da13ec4fbTadashi G. Takaoka final boolean showSettingsKeyOption = resources.getBoolean( 571503797ae0e55c74068470d237fb47c4da13ec4fbTadashi G. Takaoka R.bool.config_enable_show_settings_key_option); 57217fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa if (showSettingsKeyOption) { 57317fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa final String settingsKeyMode = prefs.getString(LatinIMESettings.PREF_SETTINGS_KEY, 57417fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa resources.getString(DEFAULT_SETTINGS_KEY_MODE)); 57517fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa // We show the settings key when 1) SETTINGS_KEY_MODE_ALWAYS_SHOW or 57617fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa // 2) SETTINGS_KEY_MODE_AUTO and there are two or more enabled IMEs on the system 57717fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa if (settingsKeyMode.equals(resources.getString(SETTINGS_KEY_MODE_ALWAYS_SHOW)) 57817fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa || (settingsKeyMode.equals(resources.getString(SETTINGS_KEY_MODE_AUTO)) 5798b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka && LatinIMEUtil.hasMultipleEnabledIMEs(context))) { 5808b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka return true; 58117fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa } 5821508c0e84f0cd93ab6f5d46fea5026e833f299bcKen Wakasa } 5838b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka return false; 5841508c0e84f0cd93ab6f5d46fea5026e833f299bcKen Wakasa } 585923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project} 586