KeyboardSwitcher.java revision cf58f53a1ab53b427a3d9784502b47ba1833b018
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; 39571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaokaimport com.android.inputmethod.latin.SubtypeSwitcher; 405cd87e1b1c4258e8d016518914eccfbb4437caceTadashi G. Takaokaimport com.android.inputmethod.latin.Utils; 415a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka 42681b676b0aecb30e644f25550018ce2b6cea3e15Tadashi G. Takaokaimport java.lang.ref.SoftReference; 4312659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaokaimport java.util.HashMap; 4412659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaokaimport java.util.Locale; 4512659d4c0ce04aaf3d8479e44f9230881b964000Tadashi G. Takaoka 46eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaokapublic class KeyboardSwitcher implements KeyboardState.SwitchActions, 47eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka SharedPreferences.OnSharedPreferenceChangeListener { 48c25e07d21261583d0eeca5aa0fb6e3ffe93dc603Tadashi G. Takaoka private static final String TAG = KeyboardSwitcher.class.getSimpleName(); 49c25e07d21261583d0eeca5aa0fb6e3ffe93dc603Tadashi G. Takaoka private static final boolean DEBUG_CACHE = LatinImeLogger.sDBG; 50f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka public static final boolean DEBUG_STATE = false; 51923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 522d9722e46c774d51c834c3a8b11261a2a22e09d3Ken Wakasa public static final String PREF_KEYBOARD_LAYOUT = "pref_keyboard_layout_20110916"; 5305ddb9a5d2b36f519a4de4b50448e258f40d2c0fTadashi G. Takaoka private static final int[] KEYBOARD_THEMES = { 5413a741999480343ccebd81ff6349b572bde17b07Tadashi G. Takaoka R.style.KeyboardTheme, 5513a741999480343ccebd81ff6349b572bde17b07Tadashi G. Takaoka R.style.KeyboardTheme_HighContrast, 5613a741999480343ccebd81ff6349b572bde17b07Tadashi G. Takaoka R.style.KeyboardTheme_Stone, 5713a741999480343ccebd81ff6349b572bde17b07Tadashi G. Takaoka R.style.KeyboardTheme_Stone_Bold, 5813a741999480343ccebd81ff6349b572bde17b07Tadashi G. Takaoka R.style.KeyboardTheme_Gingerbread, 599116bf18f9c83084f9d451e2e709eff32db27d36Tadashi G. Takaoka R.style.KeyboardTheme_IceCreamSandwich, 6075fde6489039c09056fb5e64d39630ece5ad57cfTadashi G. Takaoka }; 61979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 620ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private SubtypeSwitcher mSubtypeSwitcher; 6327d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa private SharedPreferences mPrefs; 640ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok 65f451ed2012df7eb080de045a93a494aecd2775b4Tadashi G. Takaoka private InputView mCurrentInputView; 66c84bc3460d2fb386a1db2a2c8b135b746fa706cdTadashi G. Takaoka private LatinKeyboardView mKeyboardView; 670ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private LatinIME mInputMethodService; 680a054dd1075d679385434ecef38a3d88c7551d7aTadashi G. Takaoka private String mPackageName; 690a054dd1075d679385434ecef38a3d88c7551d7aTadashi G. Takaoka private Resources mResources; 7031adfa78e2edae188edb05e869f9f68798857582satok 71b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka private KeyboardState mState; 726ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka private static final int UNSHIFT = 0; 736ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka private static final int MANUAL_SHIFT = 1; 746ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka private static final int AUTOMATIC_SHIFT = 2; 75889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 7660ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka private KeyboardId mMainKeyboardId; 7760ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka private KeyboardId mSymbolsKeyboardId; 7860ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka private KeyboardId mSymbolsShiftedKeyboardId; 79353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 80353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger private KeyboardId mCurrentId; 818b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka private final HashMap<KeyboardId, SoftReference<LatinKeyboard>> mKeyboardCache = 828b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka new HashMap<KeyboardId, SoftReference<LatinKeyboard>>(); 83466741d8a78965b8509bf527344f289e50873092Mike LeBeau 841b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka /** mIsAutoCorrectionActive indicates that auto corrected word will be input instead of 8541feaaadb758a8b31d3e436063b4b5faed104d4dsatok * what user actually typed. */ 861b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka private boolean mIsAutoCorrectionActive; 879e91472285a1b903631f1e3c998f5aa1efd3e98eTadashi G. Takaoka 885a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka private int mThemeIndex = -1; 895a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka private Context mThemeContext; 90979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 910ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private static final KeyboardSwitcher sInstance = new KeyboardSwitcher(); 920ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok 930ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok public static KeyboardSwitcher getInstance() { 940ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok return sInstance; 950ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok } 960ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok 970ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private KeyboardSwitcher() { 98e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka // Intentional empty constructor for singleton. 990ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok } 1000ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok 10127d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa public static void init(LatinIME ims, SharedPreferences prefs) { 102364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka sInstance.initInternal(ims, prefs); 103364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka } 104364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka 105364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka private void initInternal(LatinIME ims, SharedPreferences prefs) { 106364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka mInputMethodService = ims; 107364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka mPackageName = ims.getPackageName(); 108364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka mResources = ims.getResources(); 109364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka mPrefs = prefs; 110364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka mSubtypeSwitcher = SubtypeSwitcher.getInstance(); 111eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState = new KeyboardState(this); 112364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka setContextThemeWrapper(ims, getKeyboardThemeIndex(ims, prefs)); 113364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka prefs.registerOnSharedPreferenceChangeListener(this); 1145a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka } 115979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1165a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka private static int getKeyboardThemeIndex(Context context, SharedPreferences prefs) { 1175a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka final String defaultThemeId = context.getString(R.string.config_default_keyboard_theme_id); 1182d9722e46c774d51c834c3a8b11261a2a22e09d3Ken Wakasa final String themeId = prefs.getString(PREF_KEYBOARD_LAYOUT, defaultThemeId); 11905ddb9a5d2b36f519a4de4b50448e258f40d2c0fTadashi G. Takaoka try { 1205a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka final int themeIndex = Integer.valueOf(themeId); 1215a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka if (themeIndex >= 0 && themeIndex < KEYBOARD_THEMES.length) 1225a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka return themeIndex; 12305ddb9a5d2b36f519a4de4b50448e258f40d2c0fTadashi G. Takaoka } catch (NumberFormatException e) { 1245a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka // Format error, keyboard theme is default to 0. 1255a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka } 1265a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka Log.w(TAG, "Illegal keyboard theme in preference: " + themeId + ", default to 0"); 1275a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka return 0; 1285a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka } 1295a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka 1305a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka private void setContextThemeWrapper(Context context, int themeIndex) { 1315a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka if (mThemeIndex != themeIndex) { 1325a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka mThemeIndex = themeIndex; 1335a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka mThemeContext = new ContextThemeWrapper(context, KEYBOARD_THEMES[themeIndex]); 1345a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka mKeyboardCache.clear(); 13505ddb9a5d2b36f519a4de4b50448e258f40d2c0fTadashi G. Takaoka } 136979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 137979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1382ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa public void loadKeyboard(EditorInfo editorInfo, Settings.Values settingsValues) { 139979f8690967ff5409fe18f5085858ccdb8e0ccf1satok try { 1402ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa mMainKeyboardId = getKeyboardId(editorInfo, false, false, settingsValues); 1412ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa mSymbolsKeyboardId = getKeyboardId(editorInfo, true, false, settingsValues); 1422ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa mSymbolsShiftedKeyboardId = getKeyboardId(editorInfo, true, true, settingsValues); 143eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onLoadKeyboard(mResources.getString(R.string.layout_switch_back_symbols)); 144eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mPrevMainKeyboardWasShiftLocked = false; 145cf58f53a1ab53b427a3d9784502b47ba1833b018Tadashi G. Takaoka mState.onRestoreKeyboardState(); 146979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } catch (RuntimeException e) { 14760ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka Log.w(TAG, "loading keyboard failed: " + mMainKeyboardId, e); 14860ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka LatinImeLogger.logOnException(mMainKeyboardId.toString(), e); 149979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 150353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 151353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 15259f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka public void saveKeyboardState() { 1532e263b70d5769b52cba4a002e44dbf81db5de7f8Tadashi G. Takaoka if (mCurrentId != null) { 154cf58f53a1ab53b427a3d9784502b47ba1833b018Tadashi G. Takaoka mState.onSaveKeyboardState(isAlphabetMode(), isSymbolShifted()); 1552e263b70d5769b52cba4a002e44dbf81db5de7f8Tadashi G. Takaoka } 156055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka } 157055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka 158055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka public void onFinishInputView() { 159055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka mIsAutoCorrectionActive = false; 160055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka } 161055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka 162c3d175c01ff1956ddb1c2d608d69af1793b4ad8aTadashi G. Takaoka public void onHideWindow() { 163c3d175c01ff1956ddb1c2d608d69af1793b4ad8aTadashi G. Takaoka mIsAutoCorrectionActive = false; 164c3d175c01ff1956ddb1c2d608d69af1793b4ad8aTadashi G. Takaoka } 165c3d175c01ff1956ddb1c2d608d69af1793b4ad8aTadashi G. Takaoka 166055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka private void setKeyboard(final Keyboard keyboard) { 167c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka final Keyboard oldKeyboard = mKeyboardView.getKeyboard(); 168055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka mKeyboardView.setKeyboard(keyboard); 169f451ed2012df7eb080de045a93a494aecd2775b4Tadashi G. Takaoka mCurrentInputView.setKeyboardGeometry(keyboard.mTopPadding); 170055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka mCurrentId = keyboard.mId; 171eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onSetKeyboard(isAlphabetMode()); 172055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka updateShiftLockState(keyboard); 173c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka mKeyboardView.setKeyPreviewPopupEnabled( 1740a054dd1075d679385434ecef38a3d88c7551d7aTadashi G. Takaoka Settings.Values.isKeyPreviewPopupEnabled(mPrefs, mResources), 1750a054dd1075d679385434ecef38a3d88c7551d7aTadashi G. Takaoka Settings.Values.getKeyPreviewPopupDismissDelay(mPrefs, mResources)); 176050c0462dc2ada5a5afecec5b6745693c5066b85Tadashi G. Takaoka final boolean localeChanged = (oldKeyboard == null) 177055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka || !keyboard.mId.mLocale.equals(oldKeyboard.mId.mLocale); 178050c0462dc2ada5a5afecec5b6745693c5066b85Tadashi G. Takaoka mInputMethodService.mHandler.startDisplayLanguageOnSpacebar(localeChanged); 179286a5bf1c68c8dd06ece9701a904593af2457586Ken Wakasa updateShiftState(); 180353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 181353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 182055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka private void updateShiftLockState(Keyboard keyboard) { 183055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka if (mCurrentId.equals(mSymbolsShiftedKeyboardId)) { 184055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka // Symbol keyboard may have an ALT key that has a caps lock style indicator (a.k.a. 185055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka // sticky shift key). To show or dismiss the indicator, we need to call setShiftLocked() 186055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka // that takes care of the current keyboard having such ALT key or not. 187055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka keyboard.setShiftLocked(keyboard.hasShiftLockKey()); 188055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka } else if (mCurrentId.equals(mSymbolsKeyboardId)) { 189055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka // Symbol keyboard has an ALT key that has a caps lock style indicator. To disable the 190055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka // indicator, we need to call setShiftLocked(false). 191055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka keyboard.setShiftLocked(false); 192055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka } 193055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka } 194055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka 195353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger private LatinKeyboard getKeyboard(KeyboardId id) { 1968b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka final SoftReference<LatinKeyboard> ref = mKeyboardCache.get(id); 197681b676b0aecb30e644f25550018ce2b6cea3e15Tadashi G. Takaoka LatinKeyboard keyboard = (ref == null) ? null : ref.get(); 198681b676b0aecb30e644f25550018ce2b6cea3e15Tadashi G. Takaoka if (keyboard == null) { 199ef35cb631c45c8b106fe7ed9e0d1178c3e5fb963Jean Chalard final Locale savedLocale = LocaleUtils.setSystemLocale(mResources, id.mLocale); 2008da9a13760896cd78235b60d0ea680ea13620532Tadashi G. Takaoka try { 201294e1b4a5abb86e58deefc8eee40e6b661524b28Yusuke Nojima final LatinKeyboard.Builder builder = new LatinKeyboard.Builder(mThemeContext); 202294e1b4a5abb86e58deefc8eee40e6b661524b28Yusuke Nojima builder.load(id); 203294e1b4a5abb86e58deefc8eee40e6b661524b28Yusuke Nojima builder.setTouchPositionCorrectionEnabled( 204294e1b4a5abb86e58deefc8eee40e6b661524b28Yusuke Nojima mSubtypeSwitcher.currentSubtypeContainsExtraValueKey( 205294e1b4a5abb86e58deefc8eee40e6b661524b28Yusuke Nojima LatinIME.SUBTYPE_EXTRA_VALUE_SUPPORT_TOUCH_POSITION_CORRECTION)); 206294e1b4a5abb86e58deefc8eee40e6b661524b28Yusuke Nojima keyboard = builder.build(); 2078da9a13760896cd78235b60d0ea680ea13620532Tadashi G. Takaoka } finally { 208ef35cb631c45c8b106fe7ed9e0d1178c3e5fb963Jean Chalard LocaleUtils.setSystemLocale(mResources, savedLocale); 2098da9a13760896cd78235b60d0ea680ea13620532Tadashi G. Takaoka } 2108b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka mKeyboardCache.put(id, new SoftReference<LatinKeyboard>(keyboard)); 2118da9a13760896cd78235b60d0ea680ea13620532Tadashi G. Takaoka 2128da9a13760896cd78235b60d0ea680ea13620532Tadashi G. Takaoka if (DEBUG_CACHE) { 2138b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": " 21463584323cab56c76debf6bb000621f2c605329a9Tadashi G. Takaoka + ((ref == null) ? "LOAD" : "GCed") + " id=" + id 21563584323cab56c76debf6bb000621f2c605329a9Tadashi G. Takaoka + " theme=" + Keyboard.themeName(keyboard.mThemeId)); 2168da9a13760896cd78235b60d0ea680ea13620532Tadashi G. Takaoka } 217e896d31bb92146379c8b7c0050ee05eec0830317Tadashi G. Takaoka } else if (DEBUG_CACHE) { 21863584323cab56c76debf6bb000621f2c605329a9Tadashi G. Takaoka Log.d(TAG, "keyboard cache size=" + mKeyboardCache.size() + ": HIT id=" + id 21963584323cab56c76debf6bb000621f2c605329a9Tadashi G. Takaoka + " theme=" + Keyboard.themeName(keyboard.mThemeId)); 220353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 2218b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka 2221b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka keyboard.onAutoCorrectionStateChanged(mIsAutoCorrectionActive); 22373c02390d31bbf32b78763db66b04004666fb5a3Tadashi G. Takaoka keyboard.setShiftLocked(false); 2248b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka keyboard.setShifted(false); 225de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka // If the cached keyboard had been switched to another keyboard while the language was 226de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka // displayed on its spacebar, it might have had arbitrary text fade factor. In such case, 2275cd87e1b1c4258e8d016518914eccfbb4437caceTadashi G. Takaoka // we should reset the text fade factor. It is also applicable to shortcut key. 228de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka keyboard.setSpacebarTextFadeFactor(0.0f, null); 2294503e2ea9853c1573f60903d8639d82e39e07c56Tadashi G. Takaoka keyboard.updateShortcutKey(mSubtypeSwitcher.isShortcutImeReady(), null); 230681b676b0aecb30e644f25550018ce2b6cea3e15Tadashi G. Takaoka return keyboard; 231353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger } 232353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger 2332ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa private KeyboardId getKeyboardId(EditorInfo editorInfo, final boolean isSymbols, 2342ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa final boolean isShift, Settings.Values settingsValues) { 2352ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa final int mode = Utils.getKeyboardMode(editorInfo); 23659c9930ca98f68aeb6b0b9dc19e29666b8fb152aTadashi G. Takaoka final int xmlId; 23760ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka switch (mode) { 23860ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka case KeyboardId.MODE_PHONE: 23960ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka xmlId = (isSymbols && isShift) ? R.xml.kbd_phone_shift : R.xml.kbd_phone; 24060ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka break; 24160ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka case KeyboardId.MODE_NUMBER: 24260ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka xmlId = R.xml.kbd_number; 24360ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka break; 24460ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka default: 24560ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka if (isSymbols) { 24660ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka xmlId = isShift ? R.xml.kbd_symbols_shift : R.xml.kbd_symbols; 2472c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka } else { 2482c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka xmlId = R.xml.kbd_qwerty; 2492c60d6e28ecf7d6f7e97a504ebfa97e286d931edTadashi G. Takaoka } 25060ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka break; 251923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 25260ccbe16eea5ce9a874835850f257b3c88295022Tadashi G. Takaoka 253cee174b8ccb47ccddc8a8a7e88a9c617f9b5e766Ken Wakasa final boolean settingsKeyEnabled = settingsValues.isSettingsKeyEnabled(); 254ab72a97d7ce44230a0c824797d1675a5ca354a56Tadashi G. Takaoka @SuppressWarnings("deprecation") 25573e716f20284f929b2c0323c9e4759efe558de9dTadashi G. Takaoka final boolean noMicrophone = Utils.inPrivateImeOptions( 25673e716f20284f929b2c0323c9e4759efe558de9dTadashi G. Takaoka mPackageName, LatinIME.IME_OPTION_NO_MICROPHONE, editorInfo) 25773e716f20284f929b2c0323c9e4759efe558de9dTadashi G. Takaoka || Utils.inPrivateImeOptions( 25873e716f20284f929b2c0323c9e4759efe558de9dTadashi G. Takaoka null, LatinIME.IME_OPTION_NO_MICROPHONE_COMPAT, editorInfo); 25973e716f20284f929b2c0323c9e4759efe558de9dTadashi G. Takaoka final boolean voiceKeyEnabled = settingsValues.isVoiceKeyEnabled(editorInfo) 26073e716f20284f929b2c0323c9e4759efe558de9dTadashi G. Takaoka && !noMicrophone; 2612ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa final boolean voiceKeyOnMain = settingsValues.isVoiceKeyOnMain(); 2620a054dd1075d679385434ecef38a3d88c7551d7aTadashi G. Takaoka final boolean noSettingsKey = Utils.inPrivateImeOptions( 2632ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa mPackageName, LatinIME.IME_OPTION_NO_SETTINGS_KEY, editorInfo); 2642ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa final boolean hasSettingsKey = settingsKeyEnabled && !noSettingsKey; 2652ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa final int f2KeyMode = getF2KeyMode(settingsKeyEnabled, noSettingsKey); 266c3afe2c244c14ed0f8a355fe608b3402e3656330Tadashi G. Takaoka final boolean hasShortcutKey = voiceKeyEnabled && (isSymbols != voiceKeyOnMain); 267af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka final boolean forceAscii = Utils.inPrivateImeOptions( 268af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka mPackageName, LatinIME.IME_OPTION_FORCE_ASCII, editorInfo); 269af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka final boolean asciiCapable = mSubtypeSwitcher.currentSubtypeContainsExtraValueKey( 270af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka LatinIME.SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE); 271af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka final Locale locale = (forceAscii && !asciiCapable) 272af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka ? Locale.US : mSubtypeSwitcher.getInputLocale(); 2732ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa final Configuration conf = mResources.getConfiguration(); 274b39f612d9791877bf0136fa7af9ae054092b9eabTadashi G. Takaoka final DisplayMetrics dm = mResources.getDisplayMetrics(); 2750a054dd1075d679385434ecef38a3d88c7551d7aTadashi G. Takaoka 2769b6d1d52d91f8f18952ae3841f4bb0d7309bfc0eTadashi G. Takaoka return new KeyboardId( 277af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka mResources.getResourceEntryName(xmlId), xmlId, locale, conf.orientation, 278af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka dm.widthPixels, mode, editorInfo, hasSettingsKey, f2KeyMode, noSettingsKey, 279af52c0ea04c6563feaa6ea7dbac5dd87c2a48cc6Tadashi G. Takaoka voiceKeyEnabled, hasShortcutKey); 2804199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka } 2814199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka 2823a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka public int getKeyboardMode() { 283cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka return mCurrentId != null ? mCurrentId.mMode : KeyboardId.MODE_TEXT; 284923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2851679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 2863a2896c80475094f751ef447fc9c97028bfc2265Tadashi G. Takaoka public boolean isAlphabetMode() { 287571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka return mCurrentId != null && mCurrentId.isAlphabetKeyboard(); 288923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 289923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2901679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka public boolean isInputViewShown() { 29186e815a142c8aa13213151e381a8a24ef23073d3Tadashi G. Takaoka return mCurrentInputView != null && mCurrentInputView.isShown(); 2921679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka } 2931679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 2941679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka public boolean isKeyboardAvailable() { 295c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka if (mKeyboardView != null) 296c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka return mKeyboardView.getKeyboard() != null; 297b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return false; 298b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 299b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka 300050c0462dc2ada5a5afecec5b6745693c5066b85Tadashi G. Takaoka public LatinKeyboard getLatinKeyboard() { 301c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka if (mKeyboardView != null) { 302c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka final Keyboard keyboard = mKeyboardView.getKeyboard(); 303050c0462dc2ada5a5afecec5b6745693c5066b85Tadashi G. Takaoka if (keyboard instanceof LatinKeyboard) 304050c0462dc2ada5a5afecec5b6745693c5066b85Tadashi G. Takaoka return (LatinKeyboard)keyboard; 305050c0462dc2ada5a5afecec5b6745693c5066b85Tadashi G. Takaoka } 306b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return null; 3071679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka } 3081679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka 309f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka public boolean isShiftedOrShiftLocked() { 310c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka return mState.isShiftedOrShiftLocked(); 311f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka } 312f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka 313f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka public boolean isManualTemporaryUpperCase() { 314c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka return mState.isManualTemporaryUpperCase(); 315f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka } 316f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka 317eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka // Implements {@link KeyboardState.SwitchActions}. 318eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka @Override 319eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka public void setShifted(int shiftMode) { 320f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka mInputMethodService.mHandler.cancelUpdateShiftState(); 321b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka LatinKeyboard latinKeyboard = getLatinKeyboard(); 3226ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka if (latinKeyboard == null) 3236ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka return; 3246ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka if (shiftMode == AUTOMATIC_SHIFT) { 325c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka mState.setAutomaticTemporaryUpperCase(); 3266ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka latinKeyboard.setAutomaticTemporaryUpperCase(); 3276ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka } else { 3286ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka final boolean shifted = (shiftMode == MANUAL_SHIFT); 3290d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka // On non-distinct multi touch panel device, we should also turn off the shift locked 3300d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka // state when shift key is pressed to go to normal mode. 3316ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka // On the other hand, on distinct multi touch panel device, turning off the shift 3326ddb07433fc8ed8675f0996a48790a05a97b61f0Tadashi G. Takaoka // locked state with shift key pressing is handled by onReleaseShift(). 333101a00e3d4b1c29ef2ecdecd1b72b43efde7791aTadashi G. Takaoka if (!hasDistinctMultitouch() && !shifted && latinKeyboard.isShiftLocked()) { 334c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka mState.setShiftLocked(false); 3350d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka latinKeyboard.setShiftLocked(false); 3360d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka } 337c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka mState.setShifted(shifted); 3384f7f61730cbd45871c1e9044da84b494831f97c3Tadashi G. Takaoka latinKeyboard.setShifted(shifted); 339979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 3404f7f61730cbd45871c1e9044da84b494831f97c3Tadashi G. Takaoka mKeyboardView.invalidateAllKeys(); 341979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 342979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 343eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka // Implements {@link KeyboardState.SwitchActions}. 344eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka @Override 345eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka public void setShiftLocked(boolean shiftLocked) { 346f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka mInputMethodService.mHandler.cancelUpdateShiftState(); 347b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka LatinKeyboard latinKeyboard = getLatinKeyboard(); 348c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka if (latinKeyboard == null) 349c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka return; 350c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka mState.setShiftLocked(shiftLocked); 351c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka latinKeyboard.setShiftLocked(shiftLocked); 352c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka mKeyboardView.invalidateAllKeys(); 353f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka if (!shiftLocked) { 354f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka // To be able to turn off caps lock by "double tap" on shift key, we should ignore 355f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka // the second tap of the "double tap" from now for a while because we just have 356f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka // already turned off caps lock above. 357f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka mKeyboardView.startIgnoringDoubleTap(); 358f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka } 359979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 360979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 3610d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka /** 3620d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka * Toggle keyboard shift state triggered by user touch event. 3630d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka */ 364b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka public void toggleShift() { 365b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka if (DEBUG_STATE) { 366c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka Log.d(TAG, "toggleShift: " + mState); 367b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka } 368b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (isAlphabetMode()) { 369c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka setShifted(mState.isShiftedOrShiftLocked() ? UNSHIFT : MANUAL_SHIFT); 370b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } else { 3718a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka toggleShiftInSymbols(); 372b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 373b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 374b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka 375b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka public void toggleCapsLock() { 376b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka if (DEBUG_STATE) { 377c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka Log.d(TAG, "toggleCapsLock: " + mState); 378b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka } 379b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (isAlphabetMode()) { 380c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka if (mState.isShiftLocked()) { 381f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka setShiftLocked(false); 382f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka // TODO: Remove this. 383f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka // Shift key is long pressed while caps lock state, we will toggle back to normal 384f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka // state. And mark as if shift key is released. 385f47993ee34d1111fdbb1afb44fcac64a132a2e57Tadashi G. Takaoka mState.onReleaseCapsLock(); 386b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } else { 387b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka setShiftLocked(true); 388b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 389b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 390889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka } 391889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 3928a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka public void toggleKeyboardMode() { 39346831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka if (DEBUG_STATE) { 3948a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka Log.d(TAG, "toggleKeyboard: " + mState); 39546831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka } 3968a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka toggleAlphabetAndSymbols(); 39746831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka } 39846831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka 3990d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka /** 4000d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka * Update keyboard shift state triggered by connected EditText status change. 4010d0a46da0393c6dd73cccf5e22cb0dd70c99e15aTadashi G. Takaoka */ 402b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka public void updateShiftState() { 403b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka if (DEBUG_STATE) { 404c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka Log.d(TAG, "updateShiftState: " + mState 405c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka + " autoCaps=" + mInputMethodService.getCurrentAutoCapsState()); 406b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka } 407eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onUpdateShiftState(isAlphabetMode(), mInputMethodService.getCurrentAutoCapsState()); 408889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka } 409889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 410e59491460b0411bed430a5ca6eca0c56c5bf18d9Tadashi G. Takaoka public void onPressShift(boolean withSliding) { 411b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (!isKeyboardAvailable()) 412b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return; 413b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka if (DEBUG_STATE) { 414c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka Log.d(TAG, "onPressShift: " + mState + " sliding=" + withSliding); 415b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka } 416eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onPressShift(isAlphabetMode(), isSymbolShifted()); 417b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka } 418b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka 419e59491460b0411bed430a5ca6eca0c56c5bf18d9Tadashi G. Takaoka public void onReleaseShift(boolean withSliding) { 420b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (!isKeyboardAvailable()) 421b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return; 422b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka if (DEBUG_STATE) { 423c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka Log.d(TAG, "onReleaseShift: " + mState + " sliding=" + withSliding); 424b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka } 425eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onReleaseShift(isAlphabetMode(), isSymbolShifted(), withSliding); 426889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka } 427889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka 4286c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka public void onPressSymbol() { 429b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka if (DEBUG_STATE) { 430c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka Log.d(TAG, "onPressSymbol: " + mState); 431b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka } 432eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onPressSymbol(isAlphabetMode()); 4336c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka } 4346c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka 4356c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka public void onReleaseSymbol() { 436b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka if (DEBUG_STATE) { 437c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka Log.d(TAG, "onReleaseSymbol: " + mState); 438717cef79ead5d63a01d09b47caab0a3d719c69dfTadashi G. Takaoka } 439eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onReleaseSymbol(isAlphabetMode()); 4406c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka } 4416c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka 4426c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka public void onOtherKeyPressed() { 443b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka if (DEBUG_STATE) { 444c1859b8fd22b2c4cc2a700566f57f3e3d04e1580Tadashi G. Takaoka Log.d(TAG, "onOtherKeyPressed: " + mState); 445b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka } 446b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka mState.onOtherKeyPressed(); 4476c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka } 4486c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka 4495f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka public void onCancelInput() { 450eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onCancelInput(isAlphabetMode(), isSymbolShifted(), isSinglePointer()); 4515f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka } 4525f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka 453b300dbbd39b1aed738028fb538aa935a7fbd2e37Tadashi G. Takaoka // TODO: Move this variable to KeyboardState. 45446831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka private boolean mPrevMainKeyboardWasShiftLocked; 45546831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka 456eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka // Implements {@link KeyboardState.SwitchActions}. 457eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka @Override 458eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka public void setSymbolsKeyboard() { 4598a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka mPrevMainKeyboardWasShiftLocked = mState.isShiftLocked(); 4608a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka setKeyboard(getKeyboard(mSymbolsKeyboardId)); 4618a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka } 4628a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka 463eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka // Implements {@link KeyboardState.SwitchActions}. 464eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka @Override 465eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka public void setAlphabetKeyboard() { 4668a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka setKeyboard(getKeyboard(mMainKeyboardId)); 4678a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka setShiftLocked(mPrevMainKeyboardWasShiftLocked); 4688a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka mPrevMainKeyboardWasShiftLocked = false; 4698a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka } 4708a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka 471eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka // TODO: Remove this method and merge into toggleKeyboardMode(). 4728a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka private void toggleAlphabetAndSymbols() { 4738a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka if (isAlphabetMode()) { 4748a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka setSymbolsKeyboard(); 47546831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka } else { 4768a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka setAlphabetKeyboard(); 47746831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka } 47846831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka } 47946831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka 4808a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka private boolean isSymbolShifted() { 4818a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka return mCurrentId != null && mCurrentId.equals(mSymbolsShiftedKeyboardId); 4828a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka } 4838a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka 484eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka // Implements {@link KeyboardState.SwitchActions}. 485eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka @Override 486eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka public void setSymbolsShiftedKeyboard() { 4878a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka setKeyboard(getKeyboard(mSymbolsShiftedKeyboardId)); 4888a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka } 4898a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka 490eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka // TODO: Remove this method and merge into toggleShift(). 4918a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka private void toggleShiftInSymbols() { 4928a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka if (isSymbolShifted()) { 4938a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka setSymbolsKeyboard(); 4947e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka } else { 4958a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka setSymbolsShiftedKeyboard(); 496923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 497923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 498923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 499717cef79ead5d63a01d09b47caab0a3d719c69dfTadashi G. Takaoka public boolean isInMomentarySwitchState() { 500eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka return mState.isInMomentarySwitchState(); 5019e91472285a1b903631f1e3c998f5aa1efd3e98eTadashi G. Takaoka } 5029e91472285a1b903631f1e3c998f5aa1efd3e98eTadashi G. Takaoka 503cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka public boolean isVibrateAndSoundFeedbackRequired() { 504416ee19d330f08e329cce4fd7cb66003cfb64f4aTadashi G. Takaoka return mKeyboardView != null && !mKeyboardView.isInSlidingKeyInput(); 505cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka } 506cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka 50746831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka private boolean isSinglePointer() { 50846831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka return mKeyboardView != null && mKeyboardView.getPointerCount() == 1; 509b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani } 510b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani 511c8b9afe0378e3f33c3f83271bd1df9678a70c2a2Tadashi G. Takaoka public boolean hasDistinctMultitouch() { 512c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka return mKeyboardView != null && mKeyboardView.hasDistinctMultitouch(); 513c8b9afe0378e3f33c3f83271bd1df9678a70c2a2Tadashi G. Takaoka } 514c8b9afe0378e3f33c3f83271bd1df9678a70c2a2Tadashi G. Takaoka 515b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani /** 5169e91472285a1b903631f1e3c998f5aa1efd3e98eTadashi G. Takaoka * Updates state machine to figure out when to automatically snap back to the previous mode. 517b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani */ 518eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka public void onCodeInput(int code) { 51946831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka if (DEBUG_STATE) { 520eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka Log.d(TAG, "onCodeInput: code=" + code + " isSinglePointer=" + isSinglePointer() 521eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka + " " + mState); 522b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani } 523eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka mState.onCodeInput(isAlphabetMode(), isSymbolShifted(), code, isSinglePointer()); 524923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 525979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 526c84bc3460d2fb386a1db2a2c8b135b746fa706cdTadashi G. Takaoka public LatinKeyboardView getKeyboardView() { 527c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka return mKeyboardView; 528979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 529979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 530c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka public View onCreateInputView() { 531f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka return createInputView(mThemeIndex, true); 532979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 533979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 534f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka private View createInputView(final int newThemeIndex, final boolean forceRecreate) { 535f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka if (mCurrentInputView != null && mThemeIndex == newThemeIndex && !forceRecreate) 536f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka return mCurrentInputView; 537f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka 538f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka if (mKeyboardView != null) { 539f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka mKeyboardView.closing(); 540f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka } 541f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka 5425a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka final int oldThemeIndex = mThemeIndex; 543f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka Utils.GCUtils.getInstance().reset(); 544f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka boolean tryGC = true; 545f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) { 546f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka try { 5475a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka setContextThemeWrapper(mInputMethodService, newThemeIndex); 548f451ed2012df7eb080de045a93a494aecd2775b4Tadashi G. Takaoka mCurrentInputView = (InputView)LayoutInflater.from(mThemeContext).inflate( 54913a741999480343ccebd81ff6349b572bde17b07Tadashi G. Takaoka R.layout.input_view, null); 550f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka tryGC = false; 551f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka } catch (OutOfMemoryError e) { 552f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka Log.w(TAG, "load keyboard failed: " + e); 5535a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka tryGC = Utils.GCUtils.getInstance().tryGCOrWait( 5545a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka oldThemeIndex + "," + newThemeIndex, e); 555f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka } catch (InflateException e) { 556f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka Log.w(TAG, "load keyboard failed: " + e); 5575a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka tryGC = Utils.GCUtils.getInstance().tryGCOrWait( 5585a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka oldThemeIndex + "," + newThemeIndex, e); 559979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 560979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 561f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka 562c84bc3460d2fb386a1db2a2c8b135b746fa706cdTadashi G. Takaoka mKeyboardView = (LatinKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view); 5635a7a696aff6718d4e0250c394a9d01cbf2a16916Tadashi G. Takaoka mKeyboardView.setKeyboardActionListener(mInputMethodService); 5645ac4638f999db4fea8a9e24171dbceb640a10858Alan Viverette 5655ac4638f999db4fea8a9e24171dbceb640a10858Alan Viverette // This always needs to be set since the accessibility state can 5665ac4638f999db4fea8a9e24171dbceb640a10858Alan Viverette // potentially change without the input view being re-created. 5675ac4638f999db4fea8a9e24171dbceb640a10858Alan Viverette AccessibleKeyboardViewProxy.setView(mKeyboardView); 5685ac4638f999db4fea8a9e24171dbceb640a10858Alan Viverette 569f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka return mCurrentInputView; 5708d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka } 5718d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka 572f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka private void postSetInputView(final View newInputView) { 573979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mInputMethodService.mHandler.post(new Runnable() { 5748d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka @Override 575979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public void run() { 576f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka if (newInputView != null) { 577f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka mInputMethodService.setInputView(newInputView); 578979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 579979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mInputMethodService.updateInputViewShown(); 5808d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka } 5818d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka }); 582979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 583979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 5848d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka @Override 585979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 586979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (PREF_KEYBOARD_LAYOUT.equals(key)) { 5872ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa final int themeIndex = getKeyboardThemeIndex(mInputMethodService, sharedPreferences); 5882ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa postSetInputView(createInputView(themeIndex, false)); 5892ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa } else if (Settings.PREF_SHOW_SETTINGS_KEY.equals(key)) { 590f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka postSetInputView(createInputView(mThemeIndex, true)); 591979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 592979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 593979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 5941b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka public void onAutoCorrectionStateChanged(boolean isAutoCorrection) { 5955e4e05afd2825bf7acb594fef5e7bd21c751dd63Tadashi G. Takaoka if (mIsAutoCorrectionActive != isAutoCorrection) { 5961b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mIsAutoCorrectionActive = isAutoCorrection; 5975e4e05afd2825bf7acb594fef5e7bd21c751dd63Tadashi G. Takaoka final LatinKeyboard keyboard = getLatinKeyboard(); 5985e4e05afd2825bf7acb594fef5e7bd21c751dd63Tadashi G. Takaoka if (keyboard != null && keyboard.needsAutoCorrectionSpacebarLed()) { 5995e4e05afd2825bf7acb594fef5e7bd21c751dd63Tadashi G. Takaoka final Key invalidatedKey = keyboard.onAutoCorrectionStateChanged(isAutoCorrection); 600c84bc3460d2fb386a1db2a2c8b135b746fa706cdTadashi G. Takaoka final LatinKeyboardView keyboardView = getKeyboardView(); 6015e4e05afd2825bf7acb594fef5e7bd21c751dd63Tadashi G. Takaoka if (keyboardView != null) 6025e4e05afd2825bf7acb594fef5e7bd21c751dd63Tadashi G. Takaoka keyboardView.invalidateKey(invalidatedKey); 6035e4e05afd2825bf7acb594fef5e7bd21c751dd63Tadashi G. Takaoka } 60441feaaadb758a8b31d3e436063b4b5faed104d4dsatok } 60541feaaadb758a8b31d3e436063b4b5faed104d4dsatok } 6061508c0e84f0cd93ab6f5d46fea5026e833f299bcKen Wakasa 6072ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa private static int getF2KeyMode(boolean settingsKeyEnabled, boolean noSettingsKey) { 6082ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa if (noSettingsKey) { 6092ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa // Never shows the Settings key 610cd96a691b14b384face577d907f6c1aa33b47233Tadashi G. Takaoka return KeyboardId.F2KEY_MODE_SHORTCUT_IME; 611cd96a691b14b384face577d907f6c1aa33b47233Tadashi G. Takaoka } 6122ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa 6132ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa if (settingsKeyEnabled) { 6142ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa return KeyboardId.F2KEY_MODE_SETTINGS; 6152ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa } else { 6162ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa // It should be alright to fall back to the Settings key on 7-inch layouts 6172ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa // even when the Settings key is not explicitly enabled. 6182ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa return KeyboardId.F2KEY_MODE_SHORTCUT_IME_OR_SETTINGS; 6192ba975afb9529a6574148596db190b939fbc3b3fKen Wakasa } 620cd96a691b14b384face577d907f6c1aa33b47233Tadashi G. Takaoka } 621923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project} 622