KeyboardSwitcher.java revision 9b6d1d52d91f8f18952ae3841f4bb0d7309bfc0e
1923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/* 2443c360d0afdbab091994244f045f4756feaf2b4Jean-Baptiste Queru * Copyright (C) 2008 The Android Open Source Project 3571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka * 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 7571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka * 8923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka * 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 17571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaokapackage com.android.inputmethod.keyboard; 18923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 19571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaokaimport com.android.inputmethod.latin.LatinIME; 209502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaokaimport com.android.inputmethod.latin.Settings; 219502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaokaimport com.android.inputmethod.latin.Utils; 22571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaokaimport com.android.inputmethod.latin.LatinImeLogger; 23571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaokaimport com.android.inputmethod.latin.R; 24571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaokaimport com.android.inputmethod.latin.SubtypeSwitcher; 255a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka 268b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaokaimport android.content.Context; 27979f8690967ff5409fe18f5085858ccdb8e0ccf1satokimport android.content.SharedPreferences; 2836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.content.res.Resources; 298b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaokaimport android.util.Log; 30979f8690967ff5409fe18f5085858ccdb8e0ccf1satokimport android.view.InflateException; 3179efbed76f638be298493107fa2d0cd1b5eb529esatokimport android.view.inputmethod.InputMethodManager; 3236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 33681b676b0aecb30e644f25550018ce2b6cea3e15Tadashi G. Takaokaimport java.lang.ref.SoftReference; 3412659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaokaimport java.util.HashMap; 3512659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaokaimport java.util.Locale; 3612659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaoka 37979f8690967ff5409fe18f5085858ccdb8e0ccf1satokpublic class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceChangeListener { 388b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private static final String TAG = "KeyboardSwitcher"; 398b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private static final boolean DEBUG = false; 40f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka public static final boolean DEBUG_STATE = false; 41923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 4275fde6489039c09056fb5e64d39630ece5ad57cfTadashi G. Takaoka // Changing DEFAULT_LAYOUT_ID also requires prefs_for_debug.xml to be matched with. 4375fde6489039c09056fb5e64d39630ece5ad57cfTadashi G. Takaoka public static final String DEFAULT_LAYOUT_ID = "5"; 44a327485e595c9f7676989097c830ff452085d4c9satok public static final String PREF_KEYBOARD_LAYOUT = "pref_keyboard_layout_20100902"; 45979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private static final int[] THEMES = new int [] { 4675fde6489039c09056fb5e64d39630ece5ad57cfTadashi G. Takaoka R.layout.input_basic, 4775fde6489039c09056fb5e64d39630ece5ad57cfTadashi G. Takaoka R.layout.input_basic_highcontrast, 4875fde6489039c09056fb5e64d39630ece5ad57cfTadashi G. Takaoka R.layout.input_stone_normal, 4975fde6489039c09056fb5e64d39630ece5ad57cfTadashi G. Takaoka R.layout.input_stone_bold, 5075fde6489039c09056fb5e64d39630ece5ad57cfTadashi G. Takaoka R.layout.input_gingerbread, 5175fde6489039c09056fb5e64d39630ece5ad57cfTadashi G. Takaoka R.layout.input_honeycomb, // DEFAULT_LAYOUT_ID 5275fde6489039c09056fb5e64d39630ece5ad57cfTadashi G. Takaoka }; 53979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 54b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani private static final int SYMBOLS_MODE_STATE_NONE = 0; 55b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani private static final int SYMBOLS_MODE_STATE_BEGIN = 1; 56b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani private static final int SYMBOLS_MODE_STATE_SYMBOL = 2; 57b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani 580ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private SubtypeSwitcher mSubtypeSwitcher; 5927d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa private SharedPreferences mPrefs; 600ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok 613a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka private LatinKeyboardView mInputView; 620ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private LatinIME mInputMethodService; 6331adfa78e2edae188edb05e869f9f68798857582satok 64f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka private ShiftKeyState mShiftKeyState = new ShiftKeyState("Shift"); 65f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka private ModifierKeyState mSymbolKeyState = new ModifierKeyState("Symbol"); 66889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 67353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger private KeyboardId mSymbolsId; 68353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger private KeyboardId mSymbolsShiftedId; 69353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 70353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger private KeyboardId mCurrentId; 718b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private final HashMap<KeyboardId, SoftReference<LatinKeyboard>> mKeyboardCache = 728b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka new HashMap<KeyboardId, SoftReference<LatinKeyboard>>(); 73466741d8a78965b8509bf527344f289e50873092Mike LeBeau 745a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka private int mMode = KeyboardId.MODE_TEXT; /* default value */ 75923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mImeOptions; 76353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger private boolean mIsSymbols; 771b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka /** mIsAutoCorrectionActive indicates that auto corrected word will be input instead of 7841feaaadb758a8b31d3e436063b4b5faed104d4dsatok * what user actually typed. */ 791b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka private boolean mIsAutoCorrectionActive; 8004448c2978a81b8c479b254e0f40bce128da8f7bTadashi G. Takaoka private boolean mVoiceKeyEnabled; 81507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka private boolean mVoiceButtonOnPrimary; 82b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani private int mSymbolsModeState = SYMBOLS_MODE_STATE_NONE; 83923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 841508c0e84f0cd93ab6f5d46fea5026e833f299bcKen Wakasa // Indicates whether or not we have the settings key 853a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka private boolean mHasSettingsKey; 861508c0e84f0cd93ab6f5d46fea5026e833f299bcKen Wakasa private static final int SETTINGS_KEY_MODE_AUTO = R.string.settings_key_mode_auto; 87503797ae0e55c74068470d237fb47c4da13ec4fbTadashi G. Takaoka private static final int SETTINGS_KEY_MODE_ALWAYS_SHOW = 88503797ae0e55c74068470d237fb47c4da13ec4fbTadashi G. Takaoka R.string.settings_key_mode_always_show; 8917fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa // NOTE: No need to have SETTINGS_KEY_MODE_ALWAYS_HIDE here because it's not being referred to 9017fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa // in the source code now. 9117fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa // Default is SETTINGS_KEY_MODE_AUTO. 9217fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa private static final int DEFAULT_SETTINGS_KEY_MODE = SETTINGS_KEY_MODE_AUTO; 931508c0e84f0cd93ab6f5d46fea5026e833f299bcKen Wakasa 94979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private int mLayoutId; 95979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 960ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private static final KeyboardSwitcher sInstance = new KeyboardSwitcher(); 970ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok 980ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok public static KeyboardSwitcher getInstance() { 990ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok return sInstance; 1000ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok } 1010ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok 1020ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private KeyboardSwitcher() { 103e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka // Intentional empty constructor for singleton. 1040ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok } 1050ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok 10627d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa public static void init(LatinIME ims, SharedPreferences prefs) { 1070ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok sInstance.mInputMethodService = ims; 10827d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa sInstance.mPrefs = prefs; 1090ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok sInstance.mSubtypeSwitcher = SubtypeSwitcher.getInstance(); 110979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1110ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok sInstance.mLayoutId = Integer.valueOf( 1120ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok prefs.getString(PREF_KEYBOARD_LAYOUT, DEFAULT_LAYOUT_ID)); 1130ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok prefs.registerOnSharedPreferenceChangeListener(sInstance); 114979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 115979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 116e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa private void makeSymbolsKeyboardIds() { 1170ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok final Locale locale = mSubtypeSwitcher.getInputLocale(); 1189b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka final Resources res = mInputMethodService.getResources(); 1199b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka final int orientation = res.getConfiguration().orientation; 1208b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final int mode = mMode; 12159c9930ca98f68aeb6b0b9dc19e29666b8fb152aTadashi G. Takaoka final int colorScheme = getColorScheme(); 1228b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final boolean hasSettingsKey = mHasSettingsKey; 12304448c2978a81b8c479b254e0f40bce128da8f7bTadashi G. Takaoka final boolean voiceKeyEnabled = mVoiceKeyEnabled; 12404448c2978a81b8c479b254e0f40bce128da8f7bTadashi G. Takaoka final boolean hasVoiceKey = voiceKeyEnabled && !mVoiceButtonOnPrimary; 1258b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final int imeOptions = mImeOptions; 1264b8bbbadac9276df7ab587a228a84f93d74c5541Tadashi G. Takaoka // Note: This comment is only applied for phone number keyboard layout. 1274b8bbbadac9276df7ab587a228a84f93d74c5541Tadashi G. Takaoka // On non-xlarge device, "@integer/key_switch_alpha_symbol" key code is used to switch 1284b8bbbadac9276df7ab587a228a84f93d74c5541Tadashi G. Takaoka // between "phone keyboard" and "phone symbols keyboard". But on xlarge device, 1294b8bbbadac9276df7ab587a228a84f93d74c5541Tadashi G. Takaoka // "@integer/key_shift" key code is used for that purpose in order to properly display 1304b8bbbadac9276df7ab587a228a84f93d74c5541Tadashi G. Takaoka // "more" and "locked more" key labels. To achieve these behavior, we should initialize 1314b8bbbadac9276df7ab587a228a84f93d74c5541Tadashi G. Takaoka // mSymbolsId and mSymbolsShiftedId to "phone keyboard" and "phone symbols keyboard" 1324b8bbbadac9276df7ab587a228a84f93d74c5541Tadashi G. Takaoka // respectively here for xlarge device's layout switching. 1339b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka int xmlId = mode == KeyboardId.MODE_PHONE ? R.xml.kbd_phone : R.xml.kbd_symbols; 1349b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka mSymbolsId = new KeyboardId( 1359b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka res.getResourceEntryName(xmlId), xmlId, locale, orientation, mode, colorScheme, 1369b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka hasSettingsKey, voiceKeyEnabled, hasVoiceKey, imeOptions, true); 1379b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka xmlId = mode == KeyboardId.MODE_PHONE ? R.xml.kbd_phone_symbols : R.xml.kbd_symbols_shift; 1389b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka mSymbolsShiftedId = new KeyboardId( 1399b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka res.getResourceEntryName(xmlId), xmlId, locale, orientation, mode, colorScheme, 1409b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka hasSettingsKey, voiceKeyEnabled, hasVoiceKey, imeOptions, true); 141353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 142353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 1438b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private boolean hasVoiceKey(boolean isSymbols) { 14404448c2978a81b8c479b254e0f40bce128da8f7bTadashi G. Takaoka return mVoiceKeyEnabled && (isSymbols != mVoiceButtonOnPrimary); 145466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 146466741d8a78965b8509bf527344f289e50873092Mike LeBeau 14704448c2978a81b8c479b254e0f40bce128da8f7bTadashi G. Takaoka public void loadKeyboard(int mode, int imeOptions, boolean voiceKeyEnabled, 148507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka boolean voiceButtonOnPrimary) { 149e3803800c53cc813e27dd1e7c31bdb4d075f0252Amith Yamasani mSymbolsModeState = SYMBOLS_MODE_STATE_NONE; 150979f8690967ff5409fe18f5085858ccdb8e0ccf1satok try { 15104448c2978a81b8c479b254e0f40bce128da8f7bTadashi G. Takaoka loadKeyboardInternal(mode, imeOptions, voiceKeyEnabled, voiceButtonOnPrimary, 152507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka false); 153979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } catch (RuntimeException e) { 154b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka Log.w(TAG, e); 155e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa LatinImeLogger.logOnException(mode + "," + imeOptions, e); 156979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 157353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 158353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 1598b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private void loadKeyboardInternal(int mode, int imeOptions, boolean voiceButtonEnabled, 160507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka boolean voiceButtonOnPrimary, boolean isSymbols) { 1616516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani if (mInputView == null) return; 1628b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mInputView.setPreviewEnabled(mInputMethodService.getPopupOn()); 1638b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka 164923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mMode = mode; 165923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mImeOptions = imeOptions; 16604448c2978a81b8c479b254e0f40bce128da8f7bTadashi G. Takaoka mVoiceKeyEnabled = voiceButtonEnabled; 1678b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mVoiceButtonOnPrimary = voiceButtonOnPrimary; 168c5bb4591b67b165f007e29bd9424d319ac3c7c28Brandon Ballinger mIsSymbols = isSymbols; 1698b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka // Update the settings key state because number of enabled IMEs could have been changed 17027d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa mHasSettingsKey = getSettingsKeyMode(mPrefs, mInputMethodService); 1718b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka makeSymbolsKeyboardIds(); 172466741d8a78965b8509bf527344f289e50873092Mike LeBeau 173353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger KeyboardId id = getKeyboardId(mode, imeOptions, isSymbols); 1748b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka LatinKeyboard keyboard = getKeyboard(id); 175353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 176353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger mCurrentId = id; 177353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger mInputView.setKeyboard(keyboard); 178353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 179353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 180353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger private LatinKeyboard getKeyboard(KeyboardId id) { 1818b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final SoftReference<LatinKeyboard> ref = mKeyboardCache.get(id); 182681b676b0aecb30e644f25550018ce2b6cea3e15Tadashi G. Takaoka LatinKeyboard keyboard = (ref == null) ? null : ref.get(); 183681b676b0aecb30e644f25550018ce2b6cea3e15Tadashi G. Takaoka if (keyboard == null) { 1840ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok final Locale savedLocale = mSubtypeSwitcher.changeSystemLocale( 1850ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mSubtypeSwitcher.getInputLocale()); 1868b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka 187b0465116bd3786174ccd0034c8a165ebc723b60fTadashi G. Takaoka keyboard = new LatinKeyboard(mInputMethodService, id); 188358e485b14938fbcb5af5be75aa29f2b73674100Amith Yamasani 189353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger if (id.mEnableShiftLock) { 190353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger keyboard.enableShiftLock(); 191353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 1928b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka 1938b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mKeyboardCache.put(id, new SoftReference<LatinKeyboard>(keyboard)); 1948b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka if (DEBUG) 1958b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": " 1968b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka + ((ref == null) ? "LOAD" : "GCed") + " id=" + id); 19736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 1980ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mSubtypeSwitcher.changeSystemLocale(savedLocale); 1998b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka } else if (DEBUG) { 2008b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": HIT id=" + id); 201353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 2028b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka 2031b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka keyboard.onAutoCorrectionStateChanged(mIsAutoCorrectionActive); 2048b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka keyboard.setShifted(false); 205681b676b0aecb30e644f25550018ce2b6cea3e15Tadashi G. Takaoka return keyboard; 206353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 207353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 208353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger private KeyboardId getKeyboardId(int mode, int imeOptions, boolean isSymbols) { 2098b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final boolean hasVoiceKey = hasVoiceKey(isSymbols); 21059c9930ca98f68aeb6b0b9dc19e29666b8fb152aTadashi G. Takaoka final int charColorId = getColorScheme(); 21159c9930ca98f68aeb6b0b9dc19e29666b8fb152aTadashi G. Takaoka final int xmlId; 212e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa final boolean enableShiftLock; 213e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa 214e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa if (isSymbols) { 2155a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka if (mode == KeyboardId.MODE_PHONE) { 2162c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka xmlId = R.xml.kbd_phone_symbols; 2175a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka } else if (mode == KeyboardId.MODE_NUMBER) { 2182c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka // Note: MODE_NUMBER keyboard layout has no "switch alpha symbol" key. 2192c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka xmlId = R.xml.kbd_number; 2202c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka } else { 2212c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka xmlId = R.xml.kbd_symbols; 2222c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka } 223e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa enableShiftLock = false; 2242c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka } else { 2255a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka if (mode == KeyboardId.MODE_PHONE) { 2262c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka xmlId = R.xml.kbd_phone; 2272c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka enableShiftLock = false; 2285a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka } else if (mode == KeyboardId.MODE_NUMBER) { 2292c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka xmlId = R.xml.kbd_number; 2302c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka enableShiftLock = false; 2312c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka } else { 2322c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka xmlId = R.xml.kbd_qwerty; 2332c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka enableShiftLock = true; 2342c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka } 235923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2369b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka final Resources res = mInputMethodService.getResources(); 2379b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka final int orientation = res.getConfiguration().orientation; 2380ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok final Locale locale = mSubtypeSwitcher.getInputLocale(); 2399b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka return new KeyboardId( 2409b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka res.getResourceEntryName(xmlId), xmlId, locale, orientation, mode, charColorId, 24104448c2978a81b8c479b254e0f40bce128da8f7bTadashi G. Takaoka mHasSettingsKey, mVoiceKeyEnabled, hasVoiceKey, imeOptions, enableShiftLock); 242923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 243923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2443a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka public int getKeyboardMode() { 245923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return mMode; 246923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2471679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 2483a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka public boolean isAlphabetMode() { 249571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka return mCurrentId != null && mCurrentId.isAlphabetKeyboard(); 250923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 251923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2521679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka public boolean isInputViewShown() { 2531679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka return mInputView != null && mInputView.isShown(); 2541679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka } 2551679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 2561679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka public boolean isKeyboardAvailable() { 257b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (mInputView != null) 258b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return mInputView.getLatinKeyboard() != null; 259b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return false; 260b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 261b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka 262b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka private LatinKeyboard getLatinKeyboard() { 263b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (mInputView != null) 264b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return mInputView.getLatinKeyboard(); 265b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return null; 2661679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka } 2671679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 2681679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka public void setPreferredLetters(int[] frequencies) { 269b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka LatinKeyboard latinKeyboard = getLatinKeyboard(); 270b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (latinKeyboard != null) 2711679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka latinKeyboard.setPreferredLetters(frequencies); 2721679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka } 2731679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 2741679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka public void keyReleased() { 275b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka LatinKeyboard latinKeyboard = getLatinKeyboard(); 276b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (latinKeyboard != null) 2771679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka latinKeyboard.keyReleased(); 2781679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka } 2791679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 280f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka public boolean isShiftedOrShiftLocked() { 281b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka LatinKeyboard latinKeyboard = getLatinKeyboard(); 282b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (latinKeyboard != null) 283f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka return latinKeyboard.isShiftedOrShiftLocked(); 284b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return false; 2851679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka } 2861679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 2871679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka public boolean isShiftLocked() { 288b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka LatinKeyboard latinKeyboard = getLatinKeyboard(); 289b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (latinKeyboard != null) 290b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return latinKeyboard.isShiftLocked(); 291b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return false; 2921679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka } 2931679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 294f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka public boolean isAutomaticTemporaryUpperCase() { 295f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka LatinKeyboard latinKeyboard = getLatinKeyboard(); 296f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (latinKeyboard != null) 297f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka return latinKeyboard.isAutomaticTemporaryUpperCase(); 298f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka return false; 299f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka } 300f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka 301f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka public boolean isManualTemporaryUpperCase() { 302f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka LatinKeyboard latinKeyboard = getLatinKeyboard(); 303f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (latinKeyboard != null) 304f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka return latinKeyboard.isManualTemporaryUpperCase(); 305f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka return false; 306f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka } 307f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka 308f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka private void setManualTemporaryUpperCase(boolean shifted) { 309b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka LatinKeyboard latinKeyboard = getLatinKeyboard(); 3100d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka if (latinKeyboard != null) { 3110d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka // On non-distinct multi touch panel device, we should also turn off the shift locked 3120d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka // state when shift key is pressed to go to normal mode. 3130d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka // On the other hand, on distinct multi touch panel device, turning off the shift locked 3140d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka // state with shift key pressing is handled by onReleaseShift(). 3150d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka if (!hasDistinctMultitouch() && !shifted && latinKeyboard.isShiftLocked()) { 3160d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka latinKeyboard.setShiftLocked(false); 3170d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka } 3180d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka if (latinKeyboard.setShifted(shifted)) { 3190d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka mInputView.invalidateAllKeys(); 3200d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka } 321979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 322979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 323979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 324b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka private void setShiftLocked(boolean shiftLocked) { 325b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka LatinKeyboard latinKeyboard = getLatinKeyboard(); 326b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (latinKeyboard != null && latinKeyboard.setShiftLocked(shiftLocked)) { 327b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mInputView.invalidateAllKeys(); 328b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 329979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 330979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 3310d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka /** 3320d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka * Toggle keyboard shift state triggered by user touch event. 3330d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka */ 334b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka public void toggleShift() { 335b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mInputMethodService.mHandler.cancelUpdateShiftState(); 336f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (DEBUG_STATE) 337f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka Log.d(TAG, "toggleShift:" 338f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka + " keyboard=" + getLatinKeyboard().getKeyboardShiftState() 339f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka + " shiftKeyState=" + mShiftKeyState); 340b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (isAlphabetMode()) { 341f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka setManualTemporaryUpperCase(!isShiftedOrShiftLocked()); 342b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } else { 343b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka toggleShiftInSymbol(); 344b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 345b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 346b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka 347b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka public void toggleCapsLock() { 348b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mInputMethodService.mHandler.cancelUpdateShiftState(); 349f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (DEBUG_STATE) 350f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka Log.d(TAG, "toggleCapsLock:" 351f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka + " keyboard=" + getLatinKeyboard().getKeyboardShiftState() 352f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka + " shiftKeyState=" + mShiftKeyState); 353b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (isAlphabetMode()) { 354b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (isShiftLocked()) { 355f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka // Shift key is long pressed while caps lock state, we will toggle back to normal 356f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka // state. And mark as if shift key is released. 357f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka setShiftLocked(false); 358f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka mShiftKeyState.onRelease(); 359b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } else { 360b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka setShiftLocked(true); 361b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 362b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 363889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka } 364889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 365f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka private void setAutomaticTemporaryUpperCase() { 366f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka LatinKeyboard latinKeyboard = getLatinKeyboard(); 367f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (latinKeyboard != null) { 368f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka latinKeyboard.setAutomaticTemporaryUpperCase(); 369f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka mInputView.invalidateAllKeys(); 370f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka } 371f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka } 372f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka 3730d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka /** 3740d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka * Update keyboard shift state triggered by connected EditText status change. 3750d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka */ 376b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka public void updateShiftState() { 37745911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final ShiftKeyState shiftKeyState = mShiftKeyState; 378f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (DEBUG_STATE) 379f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka Log.d(TAG, "updateShiftState:" 380f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka + " autoCaps=" + mInputMethodService.getCurrentAutoCapsState() 381f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka + " keyboard=" + getLatinKeyboard().getKeyboardShiftState() 38245911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka + " shiftKeyState=" + shiftKeyState); 38345911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka if (isAlphabetMode()) { 38445911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka if (!isShiftLocked() && !shiftKeyState.isIgnoring()) { 38545911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka if (shiftKeyState.isReleasing() && mInputMethodService.getCurrentAutoCapsState()) { 38645911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka // Only when shift key is releasing, automatic temporary upper case will be set. 38745911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka setAutomaticTemporaryUpperCase(); 38845911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka } else { 38945911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka setManualTemporaryUpperCase(shiftKeyState.isMomentary()); 39045911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka } 391f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka } 39245911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka } else { 39345911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka // In symbol keyboard mode, we should clear shift key state because only alphabet 39445911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka // keyboard has shift key. 39545911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka shiftKeyState.onRelease(); 396b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 397889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka } 398889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 399b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka public void changeKeyboardMode() { 400f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (DEBUG_STATE) 401f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka Log.d(TAG, "changeKeyboardMode:" 402f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka + " keyboard=" + getLatinKeyboard().getKeyboardShiftState() 403f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka + " shiftKeyState=" + mShiftKeyState); 404b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka toggleKeyboardMode(); 405b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (isShiftLocked() && isAlphabetMode()) 406b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka setShiftLocked(true); 407b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka updateShiftState(); 408889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka } 409889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 410b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka public void onPressShift() { 411b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (!isKeyboardAvailable()) 412b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return; 413f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka ShiftKeyState shiftKeyState = mShiftKeyState; 414f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (DEBUG_STATE) 415f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka Log.d(TAG, "onPressShift:" 416f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka + " keyboard=" + getLatinKeyboard().getKeyboardShiftState() 417f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka + " shiftKeyState=" + shiftKeyState); 418f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (isAlphabetMode()) { 419f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (isShiftLocked()) { 420f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka // Shift key is pressed while caps lock state, we will treat this state as shifted 421f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka // caps lock state and mark as if shift key pressed while normal state. 422f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka shiftKeyState.onPress(); 4236769c67987f323008647f5d029c02f8cc95272eeTadashi G. Takaoka setManualTemporaryUpperCase(true); 424f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka } else if (isAutomaticTemporaryUpperCase()) { 425f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka // Shift key is pressed while automatic temporary upper case, we have to move to 426f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka // manual temporary upper case. 4276769c67987f323008647f5d029c02f8cc95272eeTadashi G. Takaoka shiftKeyState.onPress(); 428f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka setManualTemporaryUpperCase(true); 429f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka } else if (isShiftedOrShiftLocked()) { 430f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka // In manual upper case state, we just record shift key has been pressing while 431f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka // shifted state. 432f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka shiftKeyState.onPressOnShifted(); 433f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka } else { 434f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka // In base layout, chording or manual temporary upper case mode is started. 435f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka shiftKeyState.onPress(); 4366769c67987f323008647f5d029c02f8cc95272eeTadashi G. Takaoka toggleShift(); 437f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka } 438b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } else { 439f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka // In symbol mode, just toggle symbol and symbol more keyboard. 440f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka shiftKeyState.onPress(); 4416769c67987f323008647f5d029c02f8cc95272eeTadashi G. Takaoka toggleShift(); 442b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 443b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 444b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka 445b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka public void onReleaseShift() { 446b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (!isKeyboardAvailable()) 447b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return; 448f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka ShiftKeyState shiftKeyState = mShiftKeyState; 449f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (DEBUG_STATE) 450f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka Log.d(TAG, "onReleaseShift:" 451f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka + " keyboard=" + getLatinKeyboard().getKeyboardShiftState() 452f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka + " shiftKeyState=" + shiftKeyState); 453b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (isAlphabetMode()) { 454f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (shiftKeyState.isMomentary()) { 455f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka // After chording input while normal state. 456f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka toggleShift(); 457f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka } else if (isShiftLocked() && !shiftKeyState.isIgnoring()) { 458f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka // Shift has been pressed without chording while caps lock state. 459f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka toggleCapsLock(); 460f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka } else if (isShiftedOrShiftLocked() && shiftKeyState.isPressingOnShifted()) { 461f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka // Shift has been pressed without chording while shifted state. 462b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka toggleShift(); 463b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 464b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 465f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka shiftKeyState.onRelease(); 466889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka } 467889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 4686c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka public void onPressSymbol() { 469f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (DEBUG_STATE) 470f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka Log.d(TAG, "onReleaseShift:" 471f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka + " keyboard=" + getLatinKeyboard().getKeyboardShiftState() 472f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka + " symbolKeyState=" + mSymbolKeyState); 473b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka changeKeyboardMode(); 4746c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka mSymbolKeyState.onPress(); 4756c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka } 4766c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka 4776c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka public void onReleaseSymbol() { 478f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (DEBUG_STATE) 479f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka Log.d(TAG, "onReleaseShift:" 480f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka + " keyboard=" + getLatinKeyboard().getKeyboardShiftState() 481f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka + " symbolKeyState=" + mSymbolKeyState); 482b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (mSymbolKeyState.isMomentary()) 483b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka changeKeyboardMode(); 4846c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka mSymbolKeyState.onRelease(); 4856c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka } 4866c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka 4876c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka public void onOtherKeyPressed() { 48845911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka if (DEBUG_STATE) 48945911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka Log.d(TAG, "onOtherKeyPressed:" 49045911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka + " keyboard=" + getLatinKeyboard().getKeyboardShiftState() 49145911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka + " shiftKeyState=" + mShiftKeyState 49245911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka + " symbolKeyState=" + mSymbolKeyState); 493f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka mShiftKeyState.onOtherKeyPressed(); 4946c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka mSymbolKeyState.onOtherKeyPressed(); 4956c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka } 4966c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka 497b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka private void toggleShiftInSymbol() { 4987e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka if (isAlphabetMode()) 4997e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka return; 5008b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final LatinKeyboard keyboard; 5017e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka if (mCurrentId.equals(mSymbolsId) || !mCurrentId.equals(mSymbolsShiftedId)) { 502353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger mCurrentId = mSymbolsShiftedId; 5038b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka keyboard = getKeyboard(mCurrentId); 50412659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaoka // Symbol shifted keyboard has an ALT key that has a caps lock style indicator. To 50512659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaoka // enable the indicator, we need to call enableShiftLock() and setShiftLocked(true). 50612659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaoka // Thus we can keep the ALT key's Key.on value true while LatinKey.onRelease() is 50712659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaoka // called. 5088b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka keyboard.setShiftLocked(true); 5097e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka } else { 510353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger mCurrentId = mSymbolsId; 5118b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka keyboard = getKeyboard(mCurrentId); 51212659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaoka // Symbol keyboard has an ALT key that has a caps lock style indicator. To disable the 51312659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaoka // indicator, we need to call enableShiftLock() and setShiftLocked(false). 5148b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka keyboard.setShifted(false); 515923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 5168b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mInputView.setKeyboard(keyboard); 517923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 518923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 519f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka private void toggleKeyboardMode() { 52004448c2978a81b8c479b254e0f40bce128da8f7bTadashi G. Takaoka loadKeyboardInternal(mMode, mImeOptions, mVoiceKeyEnabled, mVoiceButtonOnPrimary, 521507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka !mIsSymbols); 522e354a85ef44e13999aaefd735cef7f659090f6e8Ken Wakasa if (mIsSymbols) { 523b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani mSymbolsModeState = SYMBOLS_MODE_STATE_BEGIN; 524b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani } else { 525b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani mSymbolsModeState = SYMBOLS_MODE_STATE_NONE; 526b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani } 527b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani } 528b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani 529c8b9afe0378e3f33c3f83271bd1df9678a70c2a2Tadashi G. Takaoka public boolean hasDistinctMultitouch() { 530c8b9afe0378e3f33c3f83271bd1df9678a70c2a2Tadashi G. Takaoka return mInputView != null && mInputView.hasDistinctMultitouch(); 531c8b9afe0378e3f33c3f83271bd1df9678a70c2a2Tadashi G. Takaoka } 532c8b9afe0378e3f33c3f83271bd1df9678a70c2a2Tadashi G. Takaoka 533b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani /** 534b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani * Updates state machine to figure out when to automatically switch back to alpha mode. 535b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani */ 536b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka public void onKey(int key) { 537b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka // Switch back to alpha mode if user types one or more non-space/enter 538b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka // characters followed by a space/enter 539b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani switch (mSymbolsModeState) { 540b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka case SYMBOLS_MODE_STATE_BEGIN: 541571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (key != Keyboard.CODE_SPACE && key != Keyboard.CODE_ENTER && key > 0) { 542b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mSymbolsModeState = SYMBOLS_MODE_STATE_SYMBOL; 543b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 544b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka break; 545b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka case SYMBOLS_MODE_STATE_SYMBOL: 546571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (key == Keyboard.CODE_ENTER || key == Keyboard.CODE_SPACE) { 547b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka changeKeyboardMode(); 548b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 549b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka break; 550b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani } 551923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 552979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 553979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public LatinKeyboardView getInputView() { 554979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return mInputView; 555979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 556979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 5578d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka public LatinKeyboardView onCreateInputView() { 5588d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka createInputViewInternal(mLayoutId, true); 5598d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka return mInputView; 560979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 561979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 5628d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka private void createInputViewInternal(int newLayout, boolean forceReset) { 563e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka int layoutId = newLayout; 564e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (mLayoutId != layoutId || mInputView == null || forceReset) { 565979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mInputView != null) { 566979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mInputView.closing(); 567979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 568e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (THEMES.length <= layoutId) { 569e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka layoutId = Integer.valueOf(DEFAULT_LAYOUT_ID); 570979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 571979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 5729502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka Utils.GCUtils.getInstance().reset(); 573979f8690967ff5409fe18f5085858ccdb8e0ccf1satok boolean tryGC = true; 5749502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) { 575979f8690967ff5409fe18f5085858ccdb8e0ccf1satok try { 576979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mInputView = (LatinKeyboardView) mInputMethodService.getLayoutInflater( 577e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka ).inflate(THEMES[layoutId], null); 578979f8690967ff5409fe18f5085858ccdb8e0ccf1satok tryGC = false; 579979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } catch (OutOfMemoryError e) { 5807f0befe1f0e346ec6468f229f337eda32e19f6d8Tadashi G. Takaoka Log.w(TAG, "load keyboard failed: " + e); 5819502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka tryGC = Utils.GCUtils.getInstance().tryGCOrWait( 582e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mLayoutId + "," + layoutId, e); 583979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } catch (InflateException e) { 5847f0befe1f0e346ec6468f229f337eda32e19f6d8Tadashi G. Takaoka Log.w(TAG, "load keyboard failed: " + e); 5859502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka tryGC = Utils.GCUtils.getInstance().tryGCOrWait( 586e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mLayoutId + "," + layoutId, e); 587979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 588979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 589979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mInputView.setOnKeyboardActionListener(mInputMethodService); 590e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mLayoutId = layoutId; 591979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 5928d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka } 5938d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka 5948d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka private void postSetInputView() { 595979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mInputMethodService.mHandler.post(new Runnable() { 5968d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka @Override 597979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public void run() { 598979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mInputView != null) { 599979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mInputMethodService.setInputView(mInputView); 600979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 601979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mInputMethodService.updateInputViewShown(); 6028d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka } 6038d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka }); 604979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 605979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 6068d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka @Override 607979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 608979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (PREF_KEYBOARD_LAYOUT.equals(key)) { 6098b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final int layoutId = Integer.valueOf( 6108b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka sharedPreferences.getString(key, DEFAULT_LAYOUT_ID)); 6118d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka createInputViewInternal(layoutId, false); 6128d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka postSetInputView(); 6139502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka } else if (Settings.PREF_SETTINGS_KEY.equals(key)) { 6148b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mHasSettingsKey = getSettingsKeyMode(sharedPreferences, mInputMethodService); 6158d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka createInputViewInternal(mLayoutId, true); 6168d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka postSetInputView(); 617979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 618979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 619979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 62059c9930ca98f68aeb6b0b9dc19e29666b8fb152aTadashi G. Takaoka private int getColorScheme() { 62159c9930ca98f68aeb6b0b9dc19e29666b8fb152aTadashi G. Takaoka return (mInputView != null) 6225a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka ? mInputView.getColorScheme() : KeyboardView.COLOR_SCHEME_WHITE; 623979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 624979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 6251b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka public void onAutoCorrectionStateChanged(boolean isAutoCorrection) { 6261b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka if (isAutoCorrection != mIsAutoCorrectionActive) { 62741feaaadb758a8b31d3e436063b4b5faed104d4dsatok LatinKeyboardView keyboardView = getInputView(); 6281b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mIsAutoCorrectionActive = isAutoCorrection; 62941feaaadb758a8b31d3e436063b4b5faed104d4dsatok keyboardView.invalidateKey(((LatinKeyboard) keyboardView.getKeyboard()) 6301b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka .onAutoCorrectionStateChanged(isAutoCorrection)); 63141feaaadb758a8b31d3e436063b4b5faed104d4dsatok } 63241feaaadb758a8b31d3e436063b4b5faed104d4dsatok } 6331508c0e84f0cd93ab6f5d46fea5026e833f299bcKen Wakasa 6348b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private static boolean getSettingsKeyMode(SharedPreferences prefs, Context context) { 6358b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka Resources resources = context.getResources(); 636503797ae0e55c74068470d237fb47c4da13ec4fbTadashi G. Takaoka final boolean showSettingsKeyOption = resources.getBoolean( 637503797ae0e55c74068470d237fb47c4da13ec4fbTadashi G. Takaoka R.bool.config_enable_show_settings_key_option); 63817fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa if (showSettingsKeyOption) { 6399502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka final String settingsKeyMode = prefs.getString(Settings.PREF_SETTINGS_KEY, 64017fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa resources.getString(DEFAULT_SETTINGS_KEY_MODE)); 64117fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa // We show the settings key when 1) SETTINGS_KEY_MODE_ALWAYS_SHOW or 64217fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa // 2) SETTINGS_KEY_MODE_AUTO and there are two or more enabled IMEs on the system 64317fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa if (settingsKeyMode.equals(resources.getString(SETTINGS_KEY_MODE_ALWAYS_SHOW)) 64417fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa || (settingsKeyMode.equals(resources.getString(SETTINGS_KEY_MODE_AUTO)) 6459502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka && Utils.hasMultipleEnabledIMEsOrSubtypes( 64679efbed76f638be298493107fa2d0cd1b5eb529esatok ((InputMethodManager) context.getSystemService( 64779efbed76f638be298493107fa2d0cd1b5eb529esatok Context.INPUT_METHOD_SERVICE))))) { 6488b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka return true; 64917fcd719de9a0ddcf9fd712481b28038419eec4eKen Wakasa } 6501508c0e84f0cd93ab6f5d46fea5026e833f299bcKen Wakasa } 6518b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka return false; 6521508c0e84f0cd93ab6f5d46fea5026e833f299bcKen Wakasa } 653923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project} 654