KeyboardSwitcher.java revision 7a16a061e622539e54d7d649dcb8d4965aea575a
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 19c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaokaimport android.content.Context; 20c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaokaimport android.content.SharedPreferences; 21364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaokaimport android.content.res.Configuration; 22c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaokaimport android.content.res.Resources; 23b39f612d9791877bf0136fa7af9ae054092b9eabTadashi G. Takaokaimport android.util.DisplayMetrics; 24c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaokaimport android.util.Log; 2513a741999480343ccebd81ff6349b572bde17b07Tadashi G. Takaokaimport android.view.ContextThemeWrapper; 26c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaokaimport android.view.InflateException; 27c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaokaimport android.view.LayoutInflater; 28c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaokaimport android.view.View; 29c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaokaimport android.view.inputmethod.EditorInfo; 30c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka 315ac4638f999db4fea8a9e24171dbceb640a10858Alan Viveretteimport com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy; 32b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaokaimport com.android.inputmethod.keyboard.internal.KeyboardState; 33f451ed2012df7eb080de045a93a494aecd2775b4Tadashi G. Takaokaimport com.android.inputmethod.latin.InputView; 34571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaokaimport com.android.inputmethod.latin.LatinIME; 35571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaokaimport com.android.inputmethod.latin.LatinImeLogger; 36ef35cb631c45c8b106fe7ed9e0d1178c3e5fb963Jean Chalardimport com.android.inputmethod.latin.LocaleUtils; 37571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaokaimport com.android.inputmethod.latin.R; 385cd87e1b1c4258e8d016518914eccfbb4437caceTadashi G. Takaokaimport com.android.inputmethod.latin.Settings; 397a16a061e622539e54d7d649dcb8d4965aea575aJean Chalardimport com.android.inputmethod.latin.SettingsValues; 40571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaokaimport com.android.inputmethod.latin.SubtypeSwitcher; 415cd87e1b1c4258e8d016518914eccfbb4437caceTadashi G. Takaokaimport com.android.inputmethod.latin.Utils; 425a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka 43681b676b0aecb30e644f25550018ce2b6cea3e15Tadashi G. Takaokaimport java.lang.ref.SoftReference; 4412659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaokaimport java.util.HashMap; 4512659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaokaimport java.util.Locale; 4612659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaoka 47eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaokapublic class KeyboardSwitcher implements KeyboardState.SwitchActions, 48eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka SharedPreferences.OnSharedPreferenceChangeListener { 49c25e07d21261583d0eeca5aa0fb6e3ffe93dc603Tadashi G. Takaoka private static final String TAG = KeyboardSwitcher.class.getSimpleName(); 50c25e07d21261583d0eeca5aa0fb6e3ffe93dc603Tadashi G. Takaoka private static final boolean DEBUG_CACHE = LatinImeLogger.sDBG; 51f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka public static final boolean DEBUG_STATE = false; 52923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 532d9722e46c774d51c834c3a8b11261a2a22e09d3Ken Wakasa public static final String PREF_KEYBOARD_LAYOUT = "pref_keyboard_layout_20110916"; 5405ddb9a5d2b36f519a4de4b50448e258f40d2c0fTadashi G. Takaoka private static final int[] KEYBOARD_THEMES = { 5513a741999480343ccebd81ff6349b572bde17b07Tadashi G. Takaoka R.style.KeyboardTheme, 5613a741999480343ccebd81ff6349b572bde17b07Tadashi G. Takaoka R.style.KeyboardTheme_HighContrast, 5713a741999480343ccebd81ff6349b572bde17b07Tadashi G. Takaoka R.style.KeyboardTheme_Stone, 5813a741999480343ccebd81ff6349b572bde17b07Tadashi G. Takaoka R.style.KeyboardTheme_Stone_Bold, 5913a741999480343ccebd81ff6349b572bde17b07Tadashi G. Takaoka R.style.KeyboardTheme_Gingerbread, 609116bf18f9c83084f9d451e2e709eff32db27d36Tadashi G. Takaoka R.style.KeyboardTheme_IceCreamSandwich, 6175fde6489039c09056fb5e64d39630ece5ad57cfTadashi G. Takaoka }; 62979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 630ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private SubtypeSwitcher mSubtypeSwitcher; 6427d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa private SharedPreferences mPrefs; 650ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok 66f451ed2012df7eb080de045a93a494aecd2775b4Tadashi G. Takaoka private InputView mCurrentInputView; 67c84bc3460d2fb386a1db2a2c8b135b746fa706cdTadashi G. Takaoka private LatinKeyboardView mKeyboardView; 680ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private LatinIME mInputMethodService; 690a054dd1075d679385434ecef38a3d88c7551d7aTadashi G. Takaoka private String mPackageName; 700a054dd1075d679385434ecef38a3d88c7551d7aTadashi G. Takaoka private Resources mResources; 7131adfa78e2edae188edb05e869f9f68798857582satok 72b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka private KeyboardState mState; 73889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 7460ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka private KeyboardId mMainKeyboardId; 7560ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka private KeyboardId mSymbolsKeyboardId; 7660ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka private KeyboardId mSymbolsShiftedKeyboardId; 77353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 78353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger private KeyboardId mCurrentId; 798b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private final HashMap<KeyboardId, SoftReference<LatinKeyboard>> mKeyboardCache = 808b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka new HashMap<KeyboardId, SoftReference<LatinKeyboard>>(); 81466741d8a78965b8509bf527344f289e50873092Mike LeBeau 821b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka /** mIsAutoCorrectionActive indicates that auto corrected word will be input instead of 8341feaaadb758a8b31d3e436063b4b5faed104d4dsatok * what user actually typed. */ 841b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka private boolean mIsAutoCorrectionActive; 859e91472285a1b903631f1e3c998f5aa1efd3e98eTadashi G. Takaoka 865a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka private int mThemeIndex = -1; 875a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka private Context mThemeContext; 88979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 890ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private static final KeyboardSwitcher sInstance = new KeyboardSwitcher(); 900ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok 910ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok public static KeyboardSwitcher getInstance() { 920ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok return sInstance; 930ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok } 940ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok 950ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private KeyboardSwitcher() { 96e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka // Intentional empty constructor for singleton. 970ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok } 980ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok 9927d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa public static void init(LatinIME ims, SharedPreferences prefs) { 100364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka sInstance.initInternal(ims, prefs); 101364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka } 102364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka 103364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka private void initInternal(LatinIME ims, SharedPreferences prefs) { 104364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka mInputMethodService = ims; 105364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka mPackageName = ims.getPackageName(); 106364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka mResources = ims.getResources(); 107364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka mPrefs = prefs; 108364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka mSubtypeSwitcher = SubtypeSwitcher.getInstance(); 109eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState = new KeyboardState(this); 110364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka setContextThemeWrapper(ims, getKeyboardThemeIndex(ims, prefs)); 111364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka prefs.registerOnSharedPreferenceChangeListener(this); 1125a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka } 113979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1145a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka private static int getKeyboardThemeIndex(Context context, SharedPreferences prefs) { 1155a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka final String defaultThemeId = context.getString(R.string.config_default_keyboard_theme_id); 1162d9722e46c774d51c834c3a8b11261a2a22e09d3Ken Wakasa final String themeId = prefs.getString(PREF_KEYBOARD_LAYOUT, defaultThemeId); 11705ddb9a5d2b36f519a4de4b50448e258f40d2c0fTadashi G. Takaoka try { 1185a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka final int themeIndex = Integer.valueOf(themeId); 1195a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka if (themeIndex >= 0 && themeIndex < KEYBOARD_THEMES.length) 1205a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka return themeIndex; 12105ddb9a5d2b36f519a4de4b50448e258f40d2c0fTadashi G. Takaoka } catch (NumberFormatException e) { 1225a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka // Format error, keyboard theme is default to 0. 1235a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka } 1245a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka Log.w(TAG, "Illegal keyboard theme in preference: " + themeId + ", default to 0"); 1255a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka return 0; 1265a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka } 1275a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka 1285a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka private void setContextThemeWrapper(Context context, int themeIndex) { 1295a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka if (mThemeIndex != themeIndex) { 1305a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka mThemeIndex = themeIndex; 1315a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka mThemeContext = new ContextThemeWrapper(context, KEYBOARD_THEMES[themeIndex]); 1325a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka mKeyboardCache.clear(); 13305ddb9a5d2b36f519a4de4b50448e258f40d2c0fTadashi G. Takaoka } 134979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 135979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1367a16a061e622539e54d7d649dcb8d4965aea575aJean Chalard public void loadKeyboard(EditorInfo editorInfo, SettingsValues settingsValues) { 137979f8690967ff5409fe18f5085858ccdb8e0ccf1satok try { 1382ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa mMainKeyboardId = getKeyboardId(editorInfo, false, false, settingsValues); 1392ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa mSymbolsKeyboardId = getKeyboardId(editorInfo, true, false, settingsValues); 1402ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa mSymbolsShiftedKeyboardId = getKeyboardId(editorInfo, true, true, settingsValues); 141eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onLoadKeyboard(mResources.getString(R.string.layout_switch_back_symbols)); 142979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } catch (RuntimeException e) { 14360ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka Log.w(TAG, "loading keyboard failed: " + mMainKeyboardId, e); 14460ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka LatinImeLogger.logOnException(mMainKeyboardId.toString(), e); 145979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 146353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 147353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 14859f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka public void saveKeyboardState() { 1492e263b70d5769b52cba4a002e44dbf81db5de7f8Tadashi G. Takaoka if (mCurrentId != null) { 150cf58f53a1ab53b427a3d9784502b47ba1833b018Tadashi G. Takaoka mState.onSaveKeyboardState(isAlphabetMode(), isSymbolShifted()); 1512e263b70d5769b52cba4a002e44dbf81db5de7f8Tadashi G. Takaoka } 152055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka } 153055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka 154055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka public void onFinishInputView() { 155055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka mIsAutoCorrectionActive = false; 156055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka } 157055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka 158c3d175c01ff1956ddb1c2d608d69af1793b4ad8aTadashi G. Takaoka public void onHideWindow() { 159c3d175c01ff1956ddb1c2d608d69af1793b4ad8aTadashi G. Takaoka mIsAutoCorrectionActive = false; 160c3d175c01ff1956ddb1c2d608d69af1793b4ad8aTadashi G. Takaoka } 161c3d175c01ff1956ddb1c2d608d69af1793b4ad8aTadashi G. Takaoka 162055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka private void setKeyboard(final Keyboard keyboard) { 163c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka final Keyboard oldKeyboard = mKeyboardView.getKeyboard(); 164055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka mKeyboardView.setKeyboard(keyboard); 165f451ed2012df7eb080de045a93a494aecd2775b4Tadashi G. Takaoka mCurrentInputView.setKeyboardGeometry(keyboard.mTopPadding); 166055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka mCurrentId = keyboard.mId; 167eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onSetKeyboard(isAlphabetMode()); 168055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka updateShiftLockState(keyboard); 169c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka mKeyboardView.setKeyPreviewPopupEnabled( 1707a16a061e622539e54d7d649dcb8d4965aea575aJean Chalard SettingsValues.isKeyPreviewPopupEnabled(mPrefs, mResources), 1717a16a061e622539e54d7d649dcb8d4965aea575aJean Chalard SettingsValues.getKeyPreviewPopupDismissDelay(mPrefs, mResources)); 172050c0462dc2ada5a5afecec5b6745693c5066b85Tadashi G. Takaoka final boolean localeChanged = (oldKeyboard == null) 173055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka || !keyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale); 174050c0462dc2ada5a5afecec5b6745693c5066b85Tadashi G. Takaoka mInputMethodService.mHandler.startDisplayLanguageOnSpacebar(localeChanged); 175286a5bf1c68c8dd06ece9701a904593af2457586Ken Wakasa updateShiftState(); 176353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 177353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 178055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka private void updateShiftLockState(Keyboard keyboard) { 179055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka if (mCurrentId.equals(mSymbolsShiftedKeyboardId)) { 180055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka // Symbol keyboard may have an ALT key that has a caps lock style indicator (a.k.a. 181055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka // sticky shift key). To show or dismiss the indicator, we need to call setShiftLocked() 182055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka // that takes care of the current keyboard having such ALT key or not. 183055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka keyboard.setShiftLocked(keyboard.hasShiftLockKey()); 184055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka } else if (mCurrentId.equals(mSymbolsKeyboardId)) { 185055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka // Symbol keyboard has an ALT key that has a caps lock style indicator. To disable the 186055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka // indicator, we need to call setShiftLocked(false). 187055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka keyboard.setShiftLocked(false); 188055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka } 189055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka } 190055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka 191353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger private LatinKeyboard getKeyboard(KeyboardId id) { 1928b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final SoftReference<LatinKeyboard> ref = mKeyboardCache.get(id); 193681b676b0aecb30e644f25550018ce2b6cea3e15Tadashi G. Takaoka LatinKeyboard keyboard = (ref == null) ? null : ref.get(); 194681b676b0aecb30e644f25550018ce2b6cea3e15Tadashi G. Takaoka if (keyboard == null) { 195ef35cb631c45c8b106fe7ed9e0d1178c3e5fb963Jean Chalard final Locale savedLocale = LocaleUtils.setSystemLocale(mResources, id.mLocale); 1968da9a13760896cd78235b60d0ea680ea13620532Tadashi G. Takaoka try { 197294e1b4a5abb86e58deefc8eee40e6b661524b28Yusuke Nojima final LatinKeyboard.Builder builder = new LatinKeyboard.Builder(mThemeContext); 198294e1b4a5abb86e58deefc8eee40e6b661524b28Yusuke Nojima builder.load(id); 199294e1b4a5abb86e58deefc8eee40e6b661524b28Yusuke Nojima builder.setTouchPositionCorrectionEnabled( 200294e1b4a5abb86e58deefc8eee40e6b661524b28Yusuke Nojima mSubtypeSwitcher.currentSubtypeContainsExtraValueKey( 201294e1b4a5abb86e58deefc8eee40e6b661524b28Yusuke Nojima LatinIME.SUBTYPE_EXTRA_VALUE_SUPPORT_TOUCH_POSITION_CORRECTION)); 202294e1b4a5abb86e58deefc8eee40e6b661524b28Yusuke Nojima keyboard = builder.build(); 2038da9a13760896cd78235b60d0ea680ea13620532Tadashi G. Takaoka } finally { 204ef35cb631c45c8b106fe7ed9e0d1178c3e5fb963Jean Chalard LocaleUtils.setSystemLocale(mResources, savedLocale); 2058da9a13760896cd78235b60d0ea680ea13620532Tadashi G. Takaoka } 2068b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mKeyboardCache.put(id, new SoftReference<LatinKeyboard>(keyboard)); 2078da9a13760896cd78235b60d0ea680ea13620532Tadashi G. Takaoka 2088da9a13760896cd78235b60d0ea680ea13620532Tadashi G. Takaoka if (DEBUG_CACHE) { 2098b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": " 21063584323cab56c76debf6bb000621f2c605329a9Tadashi G. Takaoka + ((ref == null) ? "LOAD" : "GCed") + " id=" + id 21163584323cab56c76debf6bb000621f2c605329a9Tadashi G. Takaoka + " theme=" + Keyboard.themeName(keyboard.mThemeId)); 2128da9a13760896cd78235b60d0ea680ea13620532Tadashi G. Takaoka } 213e896d31bb92146379c8b7c0050ee05eec0830317Tadashi G. Takaoka } else if (DEBUG_CACHE) { 21463584323cab56c76debf6bb000621f2c605329a9Tadashi G. Takaoka Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": HIT id=" + id 21563584323cab56c76debf6bb000621f2c605329a9Tadashi G. Takaoka + " theme=" + Keyboard.themeName(keyboard.mThemeId)); 216353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 2178b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka 2181b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka keyboard.onAutoCorrectionStateChanged(mIsAutoCorrectionActive); 21973c02390d31bbf32b78763db66b04004666fb5a3Tadashi G. Takaoka keyboard.setShiftLocked(false); 2208b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka keyboard.setShifted(false); 221de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka // If the cached keyboard had been switched to another keyboard while the language was 222de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka // displayed on its spacebar, it might have had arbitrary text fade factor. In such case, 2235cd87e1b1c4258e8d016518914eccfbb4437caceTadashi G. Takaoka // we should reset the text fade factor. It is also applicable to shortcut key. 224de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka keyboard.setSpacebarTextFadeFactor(0.0f, null); 2254503e2ea9853c1573f60903d8639d82e39e07c56Tadashi G. Takaoka keyboard.updateShortcutKey(mSubtypeSwitcher.isShortcutImeReady(), null); 226681b676b0aecb30e644f25550018ce2b6cea3e15Tadashi G. Takaoka return keyboard; 227353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 228353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 2292ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa private KeyboardId getKeyboardId(EditorInfo editorInfo, final boolean isSymbols, 2307a16a061e622539e54d7d649dcb8d4965aea575aJean Chalard final boolean isShift, SettingsValues settingsValues) { 2312ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa final int mode = Utils.getKeyboardMode(editorInfo); 23259c9930ca98f68aeb6b0b9dc19e29666b8fb152aTadashi G. Takaoka final int xmlId; 23360ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka switch (mode) { 23460ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka case KeyboardId.MODE_PHONE: 23560ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka xmlId = (isSymbols && isShift) ? R.xml.kbd_phone_shift : R.xml.kbd_phone; 23660ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka break; 23760ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka case KeyboardId.MODE_NUMBER: 23860ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka xmlId = R.xml.kbd_number; 23960ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka break; 24060ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka default: 24160ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka if (isSymbols) { 24260ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka xmlId = isShift ? R.xml.kbd_symbols_shift : R.xml.kbd_symbols; 2432c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka } else { 2442c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka xmlId = R.xml.kbd_qwerty; 2452c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka } 24660ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka break; 247923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 24860ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka 249cee174b8ccb47ccddc8a8a7e88a9c617f9b5e766Ken Wakasa final boolean settingsKeyEnabled = settingsValues.isSettingsKeyEnabled(); 250ab72a97d7ce44230a0c824797d1675a5ca354a56Tadashi G. Takaoka @SuppressWarnings("deprecation") 25173e716f20284f929b2c0323c9e4759efe558de9dTadashi G. Takaoka final boolean noMicrophone = Utils.inPrivateImeOptions( 25273e716f20284f929b2c0323c9e4759efe558de9dTadashi G. Takaoka mPackageName, LatinIME.IME_OPTION_NO_MICROPHONE, editorInfo) 25373e716f20284f929b2c0323c9e4759efe558de9dTadashi G. Takaoka || Utils.inPrivateImeOptions( 25473e716f20284f929b2c0323c9e4759efe558de9dTadashi G. Takaoka null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, editorInfo); 25573e716f20284f929b2c0323c9e4759efe558de9dTadashi G. Takaoka final boolean voiceKeyEnabled = settingsValues.isVoiceKeyEnabled(editorInfo) 25673e716f20284f929b2c0323c9e4759efe558de9dTadashi G. Takaoka && !noMicrophone; 2572ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa final boolean voiceKeyOnMain = settingsValues.isVoiceKeyOnMain(); 2580a054dd1075d679385434ecef38a3d88c7551d7aTadashi G. Takaoka final boolean noSettingsKey = Utils.inPrivateImeOptions( 2592ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa mPackageName, LatinIME.IME_OPTION_NO_SETTINGS_KEY, editorInfo); 2602ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa final boolean hasSettingsKey = settingsKeyEnabled && !noSettingsKey; 2612ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa final int f2KeyMode = getF2KeyMode(settingsKeyEnabled, noSettingsKey); 262c3afe2c244c14ed0f8a355fe608b3402e3656330Tadashi G. Takaoka final boolean hasShortcutKey = voiceKeyEnabled && (isSymbols != voiceKeyOnMain); 263af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka final boolean forceAscii = Utils.inPrivateImeOptions( 264af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka mPackageName, LatinIME.IME_OPTION_FORCE_ASCII, editorInfo); 265af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka final boolean asciiCapable = mSubtypeSwitcher.currentSubtypeContainsExtraValueKey( 266af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka LatinIME.SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE); 267af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka final Locale locale = (forceAscii && !asciiCapable) 268af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka ? Locale.US : mSubtypeSwitcher.getInputLocale(); 2692ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa final Configuration conf = mResources.getConfiguration(); 270b39f612d9791877bf0136fa7af9ae054092b9eabTadashi G. Takaoka final DisplayMetrics dm = mResources.getDisplayMetrics(); 2710a054dd1075d679385434ecef38a3d88c7551d7aTadashi G. Takaoka 2729b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka return new KeyboardId( 273af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka mResources.getResourceEntryName(xmlId), xmlId, locale, conf.orientation, 274af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka dm.widthPixels, mode, editorInfo, hasSettingsKey, f2KeyMode, noSettingsKey, 275af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka voiceKeyEnabled, hasShortcutKey); 2764199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka } 2774199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka 2783a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka public int getKeyboardMode() { 279cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka return mCurrentId != null ? mCurrentId.mMode : KeyboardId.MODE_TEXT; 280923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2811679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 2826ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka // TODO: Delegate to KeyboardState 2833a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka public boolean isAlphabetMode() { 284571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka return mCurrentId != null && mCurrentId.isAlphabetKeyboard(); 285923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 286923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2871679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka public boolean isInputViewShown() { 28886e815a142c8aa13213151e381a8a24ef23073d3Tadashi G. Takaoka return mCurrentInputView != null && mCurrentInputView.isShown(); 2891679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka } 2901679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 2911679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka public boolean isKeyboardAvailable() { 292c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka if (mKeyboardView != null) 293c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka return mKeyboardView.getKeyboard() != null; 294b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return false; 295b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 296b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka 297050c0462dc2ada5a5afecec5b6745693c5066b85Tadashi G. Takaoka public LatinKeyboard getLatinKeyboard() { 298c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka if (mKeyboardView != null) { 299c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka final Keyboard keyboard = mKeyboardView.getKeyboard(); 300050c0462dc2ada5a5afecec5b6745693c5066b85Tadashi G. Takaoka if (keyboard instanceof LatinKeyboard) 301050c0462dc2ada5a5afecec5b6745693c5066b85Tadashi G. Takaoka return (LatinKeyboard)keyboard; 302050c0462dc2ada5a5afecec5b6745693c5066b85Tadashi G. Takaoka } 303b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return null; 3041679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka } 3051679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 306f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka public boolean isShiftedOrShiftLocked() { 307c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka return mState.isShiftedOrShiftLocked(); 308f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka } 309f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka 310f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka public boolean isManualTemporaryUpperCase() { 311c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka return mState.isManualTemporaryUpperCase(); 312f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka } 313f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka 314eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka // Implements {@link KeyboardState.SwitchActions}. 315eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka @Override 316eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka public void setShifted(int shiftMode) { 317f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka mInputMethodService.mHandler.cancelUpdateShiftState(); 318b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka LatinKeyboard latinKeyboard = getLatinKeyboard(); 3196ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka if (latinKeyboard == null) 3206ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka return; 3216ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka if (shiftMode == AUTOMATIC_SHIFT) { 322c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka mState.setAutomaticTemporaryUpperCase(); 3236ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka latinKeyboard.setAutomaticTemporaryUpperCase(); 3246ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka } else { 3256ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka final boolean shifted = (shiftMode == MANUAL_SHIFT); 3260d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka // On non-distinct multi touch panel device, we should also turn off the shift locked 3270d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka // state when shift key is pressed to go to normal mode. 3286ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka // On the other hand, on distinct multi touch panel device, turning off the shift 3296ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka // locked state with shift key pressing is handled by onReleaseShift(). 330101a00e3d4b1c29ef2ecdecd1b72b43efde7791aTadashi G. Takaoka if (!hasDistinctMultitouch() && !shifted && latinKeyboard.isShiftLocked()) { 331c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka mState.setShiftLocked(false); 3320d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka latinKeyboard.setShiftLocked(false); 3330d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka } 334c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka mState.setShifted(shifted); 3354f7f61730cbd45871c1e9044da84b494831f97c3Tadashi G. Takaoka latinKeyboard.setShifted(shifted); 336979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 3374f7f61730cbd45871c1e9044da84b494831f97c3Tadashi G. Takaoka mKeyboardView.invalidateAllKeys(); 338979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 339979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 340eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka // Implements {@link KeyboardState.SwitchActions}. 341eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka @Override 342eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka public void setShiftLocked(boolean shiftLocked) { 343f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka mInputMethodService.mHandler.cancelUpdateShiftState(); 344b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka LatinKeyboard latinKeyboard = getLatinKeyboard(); 345c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka if (latinKeyboard == null) 346c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka return; 347c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka mState.setShiftLocked(shiftLocked); 348c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka latinKeyboard.setShiftLocked(shiftLocked); 349c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka mKeyboardView.invalidateAllKeys(); 350f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka if (!shiftLocked) { 351f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka // To be able to turn off caps lock by "double tap" on shift key, we should ignore 352f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka // the second tap of the "double tap" from now for a while because we just have 353f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka // already turned off caps lock above. 354f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka mKeyboardView.startIgnoringDoubleTap(); 355f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka } 356979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 357979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 3580d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka /** 3590d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka * Toggle keyboard shift state triggered by user touch event. 3600d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka */ 361b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka public void toggleShift() { 362b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka if (DEBUG_STATE) { 363c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka Log.d(TAG, "toggleShift: " + mState); 364b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka } 365b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (isAlphabetMode()) { 366c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka setShifted(mState.isShiftedOrShiftLocked() ? UNSHIFT : MANUAL_SHIFT); 367b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } else { 3686ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka if (isSymbolShifted()) { 3696ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka setSymbolsKeyboard(); 3706ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka } else { 3716ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka setSymbolsShiftedKeyboard(); 3726ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka } 373b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 374b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 375b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka 3766ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka /** 3776ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka * Toggle caps lock state triggered by user touch event. 3786ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka */ 379b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka public void toggleCapsLock() { 380b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka if (DEBUG_STATE) { 381c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka Log.d(TAG, "toggleCapsLock: " + mState); 382b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka } 383b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (isAlphabetMode()) { 384c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka if (mState.isShiftLocked()) { 385f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka setShiftLocked(false); 386f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka // TODO: Remove this. 387f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka // Shift key is long pressed while caps lock state, we will toggle back to normal 388f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka // state. And mark as if shift key is released. 389f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka mState.onReleaseCapsLock(); 390b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } else { 391b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka setShiftLocked(true); 392b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 393b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 394889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka } 395889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 3966ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka /** 3976ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka * Toggle keyboard mode triggered by user touch event. 3986ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka */ 3998a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka public void toggleKeyboardMode() { 40046831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka if (DEBUG_STATE) { 4016ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka Log.d(TAG, "toggleKeyboardMode: " + mState); 4026ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka } 4036ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka if (isAlphabetMode()) { 4046ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka setSymbolsKeyboard(); 4056ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka } else { 4066ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka setAlphabetKeyboard(); 40746831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka } 40846831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka } 40946831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka 4100d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka /** 4110d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka * Update keyboard shift state triggered by connected EditText status change. 4120d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka */ 413b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka public void updateShiftState() { 414b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka if (DEBUG_STATE) { 415c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka Log.d(TAG, "updateShiftState: " + mState 416c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka + " autoCaps=" + mInputMethodService.getCurrentAutoCapsState()); 417b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka } 418eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onUpdateShiftState(isAlphabetMode(), mInputMethodService.getCurrentAutoCapsState()); 419889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka } 420889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 421e59491460b0411bed430a5ca6eca0c56c5bf18d9Tadashi G. Takaoka public void onPressShift(boolean withSliding) { 422b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (!isKeyboardAvailable()) 423b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return; 424b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka if (DEBUG_STATE) { 425c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka Log.d(TAG, "onPressShift: " + mState + " sliding=" + withSliding); 426b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka } 427eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onPressShift(isAlphabetMode(), isSymbolShifted()); 428b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 429b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka 430e59491460b0411bed430a5ca6eca0c56c5bf18d9Tadashi G. Takaoka public void onReleaseShift(boolean withSliding) { 431b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (!isKeyboardAvailable()) 432b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return; 433b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka if (DEBUG_STATE) { 434c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka Log.d(TAG, "onReleaseShift: " + mState + " sliding=" + withSliding); 435b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka } 436eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onReleaseShift(isAlphabetMode(), isSymbolShifted(), withSliding); 437889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka } 438889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 4396c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka public void onPressSymbol() { 440b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka if (DEBUG_STATE) { 441c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka Log.d(TAG, "onPressSymbol: " + mState); 442b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka } 443eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onPressSymbol(isAlphabetMode()); 4446c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka } 4456c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka 4466c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka public void onReleaseSymbol() { 447b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka if (DEBUG_STATE) { 448c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka Log.d(TAG, "onReleaseSymbol: " + mState); 449717cef79ead5d63a01d09b47caab0a3d719c69dfTadashi G. Takaoka } 450eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onReleaseSymbol(isAlphabetMode()); 4516c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka } 4526c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka 4536c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka public void onOtherKeyPressed() { 454b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka if (DEBUG_STATE) { 455c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka Log.d(TAG, "onOtherKeyPressed: " + mState); 456b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka } 457b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka mState.onOtherKeyPressed(); 4586c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka } 4596c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka 4605f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka public void onCancelInput() { 461eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onCancelInput(isAlphabetMode(), isSymbolShifted(), isSinglePointer()); 4625f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka } 4635f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka 464eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka // Implements {@link KeyboardState.SwitchActions}. 465eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka @Override 466eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka public void setSymbolsKeyboard() { 4676ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka mState.onSaveShiftLockState(); 4688a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka setKeyboard(getKeyboard(mSymbolsKeyboardId)); 4698a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka } 4708a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka 471eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka // Implements {@link KeyboardState.SwitchActions}. 472eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka @Override 473eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka public void setAlphabetKeyboard() { 4748a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka setKeyboard(getKeyboard(mMainKeyboardId)); 4756ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka mState.onRestoreShiftLockState(); 47646831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka } 47746831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka 4786ad9b012d947458155609e418aaeb3904cf27f6fTadashi G. Takaoka // TODO: Remove this method 4798a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka private boolean isSymbolShifted() { 4808a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka return mCurrentId != null && mCurrentId.equals(mSymbolsShiftedKeyboardId); 4818a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka } 4828a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka 483eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka // Implements {@link KeyboardState.SwitchActions}. 484eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka @Override 485eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka public void setSymbolsShiftedKeyboard() { 4868a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka setKeyboard(getKeyboard(mSymbolsShiftedKeyboardId)); 4878a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka } 4888a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka 489717cef79ead5d63a01d09b47caab0a3d719c69dfTadashi G. Takaoka public boolean isInMomentarySwitchState() { 490eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka return mState.isInMomentarySwitchState(); 4919e91472285a1b903631f1e3c998f5aa1efd3e98eTadashi G. Takaoka } 4929e91472285a1b903631f1e3c998f5aa1efd3e98eTadashi G. Takaoka 493cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka public boolean isVibrateAndSoundFeedbackRequired() { 494416ee19d330f08e329cce4fd7cb66003cfb64f4aTadashi G. Takaoka return mKeyboardView != null && !mKeyboardView.isInSlidingKeyInput(); 495cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka } 496cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka 49746831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka private boolean isSinglePointer() { 49846831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka return mKeyboardView != null && mKeyboardView.getPointerCount() == 1; 499b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani } 500b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani 501c8b9afe0378e3f33c3f83271bd1df9678a70c2a2Tadashi G. Takaoka public boolean hasDistinctMultitouch() { 502c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka return mKeyboardView != null && mKeyboardView.hasDistinctMultitouch(); 503c8b9afe0378e3f33c3f83271bd1df9678a70c2a2Tadashi G. Takaoka } 504c8b9afe0378e3f33c3f83271bd1df9678a70c2a2Tadashi G. Takaoka 505b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani /** 5069e91472285a1b903631f1e3c998f5aa1efd3e98eTadashi G. Takaoka * Updates state machine to figure out when to automatically snap back to the previous mode. 507b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani */ 508eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka public void onCodeInput(int code) { 50946831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka if (DEBUG_STATE) { 510eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka Log.d(TAG, "onCodeInput: code=" + code + " isSinglePointer=" + isSinglePointer() 511eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka + " " + mState); 512b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani } 513eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onCodeInput(isAlphabetMode(), isSymbolShifted(), code, isSinglePointer()); 514923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 515979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 516c84bc3460d2fb386a1db2a2c8b135b746fa706cdTadashi G. Takaoka public LatinKeyboardView getKeyboardView() { 517c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka return mKeyboardView; 518979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 519979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 520c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka public View onCreateInputView() { 521f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka return createInputView(mThemeIndex, true); 522979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 523979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 524f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka private View createInputView(final int newThemeIndex, final boolean forceRecreate) { 525f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka if (mCurrentInputView != null && mThemeIndex == newThemeIndex && !forceRecreate) 526f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka return mCurrentInputView; 527f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka 528f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka if (mKeyboardView != null) { 529f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka mKeyboardView.closing(); 530f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka } 531f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka 5325a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka final int oldThemeIndex = mThemeIndex; 533f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka Utils.GCUtils.getInstance().reset(); 534f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka boolean tryGC = true; 535f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) { 536f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka try { 5375a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka setContextThemeWrapper(mInputMethodService, newThemeIndex); 538f451ed2012df7eb080de045a93a494aecd2775b4Tadashi G. Takaoka mCurrentInputView = (InputView)LayoutInflater.from(mThemeContext).inflate( 53913a741999480343ccebd81ff6349b572bde17b07Tadashi G. Takaoka R.layout.input_view, null); 540f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka tryGC = false; 541f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka } catch (OutOfMemoryError e) { 542f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka Log.w(TAG, "load keyboard failed: " + e); 5435a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka tryGC = Utils.GCUtils.getInstance().tryGCOrWait( 5445a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka oldThemeIndex + "," + newThemeIndex, e); 545f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka } catch (InflateException e) { 546f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka Log.w(TAG, "load keyboard failed: " + e); 5475a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka tryGC = Utils.GCUtils.getInstance().tryGCOrWait( 5485a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka oldThemeIndex + "," + newThemeIndex, e); 549979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 550979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 551f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka 552c84bc3460d2fb386a1db2a2c8b135b746fa706cdTadashi G. Takaoka mKeyboardView = (LatinKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view); 5535a7a696aff6718d4e0250c394a9d01cbf2a16916Tadashi G. Takaoka mKeyboardView.setKeyboardActionListener(mInputMethodService); 5545ac4638f999db4fea8a9e24171dbceb640a10858Alan Viverette 5555ac4638f999db4fea8a9e24171dbceb640a10858Alan Viverette // This always needs to be set since the accessibility state can 5565ac4638f999db4fea8a9e24171dbceb640a10858Alan Viverette // potentially change without the input view being re-created. 5575ac4638f999db4fea8a9e24171dbceb640a10858Alan Viverette AccessibleKeyboardViewProxy.setView(mKeyboardView); 5585ac4638f999db4fea8a9e24171dbceb640a10858Alan Viverette 559f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka return mCurrentInputView; 5608d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka } 5618d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka 562f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka private void postSetInputView(final View newInputView) { 563979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mInputMethodService.mHandler.post(new Runnable() { 5648d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka @Override 565979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public void run() { 566f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka if (newInputView != null) { 567f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka mInputMethodService.setInputView(newInputView); 568979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 569979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mInputMethodService.updateInputViewShown(); 5708d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka } 5718d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka }); 572979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 573979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 5748d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka @Override 575979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 576979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (PREF_KEYBOARD_LAYOUT.equals(key)) { 5772ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa final int themeIndex = getKeyboardThemeIndex(mInputMethodService, sharedPreferences); 5782ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa postSetInputView(createInputView(themeIndex, false)); 5792ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa } else if (Settings.PREF_SHOW_SETTINGS_KEY.equals(key)) { 580f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka postSetInputView(createInputView(mThemeIndex, true)); 581979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 582979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 583979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 5841b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka public void onAutoCorrectionStateChanged(boolean isAutoCorrection) { 5855e4e05afd2825bf7acb594fef5e7bd21c751dd63Tadashi G. Takaoka if (mIsAutoCorrectionActive != isAutoCorrection) { 5861b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mIsAutoCorrectionActive = isAutoCorrection; 5875e4e05afd2825bf7acb594fef5e7bd21c751dd63Tadashi G. Takaoka final LatinKeyboard keyboard = getLatinKeyboard(); 5885e4e05afd2825bf7acb594fef5e7bd21c751dd63Tadashi G. Takaoka if (keyboard != null && keyboard.needsAutoCorrectionSpacebarLed()) { 5895e4e05afd2825bf7acb594fef5e7bd21c751dd63Tadashi G. Takaoka final Key invalidatedKey = keyboard.onAutoCorrectionStateChanged(isAutoCorrection); 590c84bc3460d2fb386a1db2a2c8b135b746fa706cdTadashi G. Takaoka final LatinKeyboardView keyboardView = getKeyboardView(); 5915e4e05afd2825bf7acb594fef5e7bd21c751dd63Tadashi G. Takaoka if (keyboardView != null) 5925e4e05afd2825bf7acb594fef5e7bd21c751dd63Tadashi G. Takaoka keyboardView.invalidateKey(invalidatedKey); 5935e4e05afd2825bf7acb594fef5e7bd21c751dd63Tadashi G. Takaoka } 59441feaaadb758a8b31d3e436063b4b5faed104d4dsatok } 59541feaaadb758a8b31d3e436063b4b5faed104d4dsatok } 5961508c0e84f0cd93ab6f5d46fea5026e833f299bcKen Wakasa 5972ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa private static int getF2KeyMode(boolean settingsKeyEnabled, boolean noSettingsKey) { 5982ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa if (noSettingsKey) { 5992ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa // Never shows the Settings key 600cd96a691b14b384face577d907f6c1aa33b47233Tadashi G. Takaoka return KeyboardId.F2KEY_MODE_SHORTCUT_IME; 601cd96a691b14b384face577d907f6c1aa33b47233Tadashi G. Takaoka } 6022ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa 6032ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa if (settingsKeyEnabled) { 6042ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa return KeyboardId.F2KEY_MODE_SETTINGS; 6052ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa } else { 6062ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa // It should be alright to fall back to the Settings key on 7-inch layouts 6072ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa // even when the Settings key is not explicitly enabled. 6082ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa return KeyboardId.F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS; 6092ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa } 610cd96a691b14b384face577d907f6c1aa33b47233Tadashi G. Takaoka } 611923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project} 612