LatinIME.java revision f733074aaecdfd6e89cfee2daff8a9c1233b60f1
1923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/* 2443c360d0afdbab091994244f045f4756feaf2b4Jean-Baptiste Queru * Copyright (C) 2008 The Android Open Source Project 3c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * 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 7a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker * 8923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker * 10923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * License for the specific language governing permissions and limitations under 14923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * the License. 15923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 16923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 17923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectpackage com.android.inputmethod.latin; 18923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 192cff4d7e4abdb192151f9b4027fc93fe28a8bdaasatokimport com.android.inputmethod.compat.CompatUtils; 20b2707856aba4fc9b063f26305f1fb603b19c1701satokimport com.android.inputmethod.compat.EditorInfoCompatUtils; 21b2707856aba4fc9b063f26305f1fb603b19c1701satokimport com.android.inputmethod.compat.InputConnectionCompatUtils; 22610f1dc8553cf2ed97e763a06a19380c4a6cd636satokimport com.android.inputmethod.compat.InputMethodManagerCompatWrapper; 2310dd34de0ffcde0104f7d2dae3a3c9fd66abffccsatokimport com.android.inputmethod.compat.InputMethodServiceCompatWrapper; 24e9957752bcaad048746c7a57bbd2c0a59e1918a0satokimport com.android.inputmethod.compat.InputTypeCompatUtils; 25699e429f1913197650cc2fc2d8cb6e506be66842satokimport com.android.inputmethod.compat.VibratorCompatWrapper; 2688fc9d44186120f9edc5cf7ec0e2af85260fed04satokimport com.android.inputmethod.deprecated.LanguageSwitcherProxy; 27e9957752bcaad048746c7a57bbd2c0a59e1918a0satokimport com.android.inputmethod.deprecated.VoiceProxy; 28f733074aaecdfd6e89cfee2daff8a9c1233b60f1satokimport com.android.inputmethod.deprecated.recorrection.Recorrection; 295a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaokaimport com.android.inputmethod.keyboard.Keyboard; 305a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardActionListener; 31571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardSwitcher; 325a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardView; 33de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaokaimport com.android.inputmethod.keyboard.LatinKeyboard; 345a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaokaimport com.android.inputmethod.keyboard.LatinKeyboardView; 35388ce92ab8a635c5ad44620dad59baf05dfea510Amith Yamasani 36923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.app.AlertDialog; 37923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.BroadcastReceiver; 38923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.Context; 39923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.DialogInterface; 40923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.Intent; 41923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.IntentFilter; 42923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.SharedPreferences; 43923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.res.Configuration; 4436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.content.res.Resources; 45923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.inputmethodservice.InputMethodService; 46923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.media.AudioManager; 47123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaokaimport android.net.ConnectivityManager; 48923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.Debug; 49923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.Handler; 5018e15a1e5e30cf200e935e43a73edef25682de27Ken Wakasaimport android.os.IBinder; 51923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.Message; 52923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.SystemClock; 53bf96661d33d0126adb60a48880ceba1ff055d4a4satokimport android.preference.PreferenceActivity; 54923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.preference.PreferenceManager; 55e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaokaimport android.text.InputType; 56923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.text.TextUtils; 57979f8690967ff5409fe18f5085858ccdb8e0ccf1satokimport android.util.DisplayMetrics; 58923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.util.Log; 59923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.util.PrintWriterPrinter; 60923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.util.Printer; 6166a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasaniimport android.view.HapticFeedbackConstants; 62923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.KeyEvent; 63e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaokaimport android.view.LayoutInflater; 64923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.View; 658e09172df1bb176cc899940862c56bed9b9aec4esatokimport android.view.ViewGroup; 668e09172df1bb176cc899940862c56bed9b9aec4esatokimport android.view.ViewParent; 67923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.Window; 68923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.WindowManager; 69923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.inputmethod.CompletionInfo; 70923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.inputmethod.EditorInfo; 71466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport android.view.inputmethod.ExtractedText; 72923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.inputmethod.InputConnection; 7340ac45ebdcd71940394dda00371d4847f7db0f26Ken Wakasaimport android.widget.LinearLayout; 74923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 75466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport java.io.FileDescriptor; 76466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport java.io.PrintWriter; 77b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimodaimport java.util.Arrays; 78466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport java.util.Locale; 79466741d8a78965b8509bf527344f289e50873092Mike LeBeau 80923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/** 81923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Input method implementation for Qwerty'ish keyboard. 82923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 8310dd34de0ffcde0104f7d2dae3a3c9fd66abffccsatokpublic class LatinIME extends InputMethodServiceCompatWrapper implements KeyboardActionListener { 848efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka private static final String TAG = LatinIME.class.getSimpleName(); 85979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private static final boolean PERF_DEBUG = false; 86409220583333bdf06290dd9fd42f91b5c0d1b11asatok private static final boolean TRACE = false; 87910b73127fa207dd26ec8124000262523b0aac0csatok private static boolean DEBUG = LatinImeLogger.sDBG; 88a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 898efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka /** 908efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka * The private IME option used to indicate that no microphone should be 918efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka * shown for a given text field. For instance, this is specified by the 928efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka * search dialog when the dialog is already showing a voice search button. 938efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka * 948efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka * @deprecated Use {@link LatinIME#IME_OPTION_NO_MICROPHONE} with package name prefixed. 958efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka */ 9610dd34de0ffcde0104f7d2dae3a3c9fd66abffccsatok @SuppressWarnings("dep-ann") 978efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka public static final String IME_OPTION_NO_MICROPHONE_COMPAT = "nm"; 988efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka 998efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka /** 1008efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka * The private IME option used to indicate that no microphone should be 1018efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka * shown for a given text field. For instance, this is specified by the 1028efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka * search dialog when the dialog is already showing a voice search button. 1038efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka */ 1044199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka public static final String IME_OPTION_NO_MICROPHONE = "noMicrophoneKey"; 1054199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka 1064199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka /** 1074199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka * The private IME option used to indicate that no settings key should be 1084199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka * shown for a given text field. 1094199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka */ 1104199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka public static final String IME_OPTION_NO_SETTINGS_KEY = "noSettingsKey"; 1118efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka 1129e347d3d448e48229c46aad394ec9bd60cd5807bsatok private static final int EXTENDED_TOUCHABLE_REGION_HEIGHT = 100; 113fd0bd57deb53c4cce32810a61133fa44b45dbb7bKen Wakasa 114923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // How many continuous deletes at which to start deleting at a higher speed. 115923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private static final int DELETE_ACCELERATE_AT = 20; 116923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Key events coming any faster than this are long-presses. 117d67fe0e7583f1be18b35b33b7658e4427f1e3dedAmith Yamasani private static final int QUICK_PRESS = 200; 118a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 119cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard /** 120cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard * The name of the scheme used by the Package Manager to warn of a new package installation, 121cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard * replacement or removal. 122cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard */ 123cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard private static final String SCHEME_PACKAGE = "package"; 124cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard 1257599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private int mSuggestionVisibility; 1267599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private static final int SUGGESTION_VISIBILILTY_SHOW_VALUE 1277599cfea4a2d56f4779452ec8e8742f7b9629cc0satok = R.string.prefs_suggestion_visibility_show_value; 1287599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private static final int SUGGESTION_VISIBILILTY_SHOW_ONLY_PORTRAIT_VALUE 1297599cfea4a2d56f4779452ec8e8742f7b9629cc0satok = R.string.prefs_suggestion_visibility_show_only_portrait_value; 1307599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private static final int SUGGESTION_VISIBILILTY_HIDE_VALUE 1317599cfea4a2d56f4779452ec8e8742f7b9629cc0satok = R.string.prefs_suggestion_visibility_hide_value; 1327599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 1337599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private static final int[] SUGGESTION_VISIBILITY_VALUE_ARRAY = new int[] { 1347599cfea4a2d56f4779452ec8e8742f7b9629cc0satok SUGGESTION_VISIBILILTY_SHOW_VALUE, 1357599cfea4a2d56f4779452ec8e8742f7b9629cc0satok SUGGESTION_VISIBILILTY_SHOW_ONLY_PORTRAIT_VALUE, 1367599cfea4a2d56f4779452ec8e8742f7b9629cc0satok SUGGESTION_VISIBILILTY_HIDE_VALUE 1377599cfea4a2d56f4779452ec8e8742f7b9629cc0satok }; 1387599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 139e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka private View mCandidateViewContainer; 1407a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka private int mCandidateStripHeight; 141923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private CandidateView mCandidateView; 142923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private Suggest mSuggest; 1431b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka private CompletionInfo[] mApplicationSpecifiedCompletions; 144a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 145923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private AlertDialog mOptionsDialog; 146a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 147610f1dc8553cf2ed97e763a06a19380c4a6cd636satok private InputMethodManagerCompatWrapper mImm; 1482fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private Resources mResources; 1492fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private SharedPreferences mPrefs; 1502fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private String mInputMethodId; 15171c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka private KeyboardSwitcher mKeyboardSwitcher; 1520ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private SubtypeSwitcher mSubtypeSwitcher; 153b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok private VoiceProxy mVoiceProxy; 1547a8dac55278cedd838be325f56b4c52d973c61f5satok private Recorrection mRecorrection; 155a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 156923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private UserDictionary mUserDictionary; 157979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private UserBigramDictionary mUserBigramDictionary; 1582bed1531c2c9bd48096bfa97dd1a39e04bd15e7bEric Fischer private ContactsDictionary mContactsDictionary; 1594ff60be170872503cca0275ef3488b7379b5311bAmith Yamasani private AutoDictionary mAutoDictionary; 16036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 1610730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard // TODO: Create an inner class to group options and pseudo-options to improve readability. 162c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // These variables are initialized according to the {@link EditorInfo#inputType}. 1630730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard private boolean mShouldInsertMagicSpace; 164c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka private boolean mInputTypeNoAutoCorrect; 165c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka private boolean mIsSettingsSuggestionStripOn; 166c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka private boolean mApplicationSpecifiedCompletionOn; 167c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 168dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette private AccessibilityUtils mAccessibilityUtils; 169dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette 17071c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka private final StringBuilder mComposing = new StringBuilder(); 171923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private WordComposer mWord = new WordComposer(); 172923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private CharSequence mBestWord; 173f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard private boolean mHasUncommittedTypedChars; 174e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani private boolean mHasDictionary; 1750730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard // Magic space: a space that should disappear on space/apostrophe insertion, move after the 1760730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard // punctuation on punctuation insertion, and become a real space on alpha char insertion. 1770730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard private boolean mJustAddedMagicSpace; // This indicates whether the last char is a magic space. 178e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani private boolean mAutoCorrectEnabled; 179b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard // Suggestion: use bigrams to adjust scores of suggestions obtained from unigram dictionary 180979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean mBigramSuggestionEnabled; 181b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard // Prediction: use bigrams to predict the next word when there is no input for it yet 182b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard private boolean mBigramPredictionEnabled; 183923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mAutoCorrectOn; 184923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mVibrateOn; 185923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mSoundOn; 186979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean mPopupOn; 187923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mAutoCap; 1886e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani private boolean mQuickFixes; 1892fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private boolean mConfigEnableShowSubtypeSettings; 190363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka private boolean mConfigSwipeDownDismissKeyboardEnabled; 191de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka private int mConfigDelayBeforeFadeoutLanguageOnSpacebar; 1929b2192bfd2d3a06df3c685ed4287e192dbaabf32Ken Wakasa private int mConfigDelayUpdateSuggestions; 1939b2192bfd2d3a06df3c685ed4287e192dbaabf32Ken Wakasa private int mConfigDelayUpdateOldSuggestions; 1949b2192bfd2d3a06df3c685ed4287e192dbaabf32Ken Wakasa private int mConfigDelayUpdateShiftState; 195de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka private int mConfigDurationOfFadeoutLanguageOnSpacebar; 196d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka private float mConfigFinalFadeoutFactorOfLanguageOnSpacebar; 197fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka private long mConfigDoubleSpacesTurnIntoPeriodTimeout; 198409220583333bdf06290dd9fd42f91b5c0d1b11asatok 19979efbed76f638be298493107fa2d0cd1b5eb529esatok private int mCorrectionMode; 20079efbed76f638be298493107fa2d0cd1b5eb529esatok private int mCommittedLength; 20179efbed76f638be298493107fa2d0cd1b5eb529esatok private int mOrientation; 202979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Keep track of the last selection range to decide if we need to show word alternatives 20379efbed76f638be298493107fa2d0cd1b5eb529esatok private int mLastSelectionStart; 20479efbed76f638be298493107fa2d0cd1b5eb529esatok private int mLastSelectionEnd; 2057e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka private SuggestedWords mSuggestPuncList; 206979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 207923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Indicates whether the suggestion strip is to be on in landscape 208923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mJustAccepted; 209923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mDeleteCount; 210923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private long mLastKeyTime; 211a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 212923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private AudioManager mAudioManager; 2132296317b8f0209789f797ac8a2fcb70e03f6d001Eric Laurent // Align sound effect volume on music volume 21471c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka private static final float FX_VOLUME = -1.0f; 215923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mSilentMode; 216923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 217979f8690967ff5409fe18f5085858ccdb8e0ccf1satok /* package */ String mWordSeparators; 218863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard private String mMagicSpaceStrippers; 219863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard private String mMagicSpaceSwappers; 220979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private String mSuggestPuncs; 221b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok // TODO: Move this flag to VoiceProxy 22281c52293f84ce475ac6b1661f4a4b92703405247Amith Yamasani private boolean mConfigurationChanging; 223466741d8a78965b8509bf527344f289e50873092Mike LeBeau 224cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard // Object for reacting to adding/removing a dictionary pack. 225cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard private BroadcastReceiver mDictionaryPackInstallReceiver = 226cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard new DictionaryPackInstallBroadcastReceiver(this); 227cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard 228dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani // Keeps track of most recently inserted text (multi-character key) for reverting 229dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani private CharSequence mEnteredText; 230dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani 23136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 232571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka public final UIHandler mHandler = new UIHandler(); 233d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 234409220583333bdf06290dd9fd42f91b5c0d1b11asatok public class UIHandler extends Handler { 235d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int MSG_UPDATE_SUGGESTIONS = 0; 236d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int MSG_UPDATE_OLD_SUGGESTIONS = 1; 237d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int MSG_UPDATE_SHIFT_STATE = 2; 238d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int MSG_VOICE_RESULTS = 3; 239de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka private static final int MSG_FADEOUT_LANGUAGE_ON_SPACEBAR = 4; 240de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka private static final int MSG_DISMISS_LANGUAGE_ON_SPACEBAR = 5; 241fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka private static final int MSG_SPACE_TYPED = 6; 242cb3320179d39a7983874697a0aa428b127675c9dJean Chalard private static final int MSG_SET_BIGRAM_PREDICTIONS = 7; 243d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 244923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 245923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void handleMessage(Message msg) { 246de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka final KeyboardSwitcher switcher = mKeyboardSwitcher; 247de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka final LatinKeyboardView inputView = switcher.getInputView(); 248923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (msg.what) { 249d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka case MSG_UPDATE_SUGGESTIONS: 250d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka updateSuggestions(); 251d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 252d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka case MSG_UPDATE_OLD_SUGGESTIONS: 2539fbfd5877305ed19a20663630b498b6b3fdae942satok mRecorrection.setRecorrectionSuggestions(mVoiceProxy, mCandidateView, mSuggest, 2549fbfd5877305ed19a20663630b498b6b3fdae942satok mKeyboardSwitcher, mWord, mHasUncommittedTypedChars, mLastSelectionStart, 2559fbfd5877305ed19a20663630b498b6b3fdae942satok mLastSelectionEnd, mWordSeparators); 256d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 257d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka case MSG_UPDATE_SHIFT_STATE: 258de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka switcher.updateShiftState(); 259d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 260cb3320179d39a7983874697a0aa428b127675c9dJean Chalard case MSG_SET_BIGRAM_PREDICTIONS: 261cb3320179d39a7983874697a0aa428b127675c9dJean Chalard updateBigramPredictions(); 26289bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard break; 263d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka case MSG_VOICE_RESULTS: 264b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.handleVoiceResults(preferCapitalization() 265de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka || (switcher.isAlphabetMode() && switcher.isShiftedOrShiftLocked())); 266de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka break; 267de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka case MSG_FADEOUT_LANGUAGE_ON_SPACEBAR: 268de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (inputView != null) 26966432cfc9b7680a653bcf19d0d4250db21155eceTadashi G. Takaoka inputView.setSpacebarTextFadeFactor( 270d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka (1.0f + mConfigFinalFadeoutFactorOfLanguageOnSpacebar) / 2, 27166432cfc9b7680a653bcf19d0d4250db21155eceTadashi G. Takaoka (LatinKeyboard)msg.obj); 272de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_DISMISS_LANGUAGE_ON_SPACEBAR, msg.obj), 273de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka mConfigDurationOfFadeoutLanguageOnSpacebar); 274de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka break; 275de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka case MSG_DISMISS_LANGUAGE_ON_SPACEBAR: 276de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (inputView != null) 27766432cfc9b7680a653bcf19d0d4250db21155eceTadashi G. Takaoka inputView.setSpacebarTextFadeFactor( 278d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka mConfigFinalFadeoutFactorOfLanguageOnSpacebar, (LatinKeyboard)msg.obj); 279d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 280923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 281923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 282d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 283d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void postUpdateSuggestions() { 284d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_SUGGESTIONS); 2859b2192bfd2d3a06df3c685ed4287e192dbaabf32Ken Wakasa sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTIONS), 2869b2192bfd2d3a06df3c685ed4287e192dbaabf32Ken Wakasa mConfigDelayUpdateSuggestions); 287d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 288d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 289d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void cancelUpdateSuggestions() { 290d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_SUGGESTIONS); 291d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 292d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 293d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public boolean hasPendingUpdateSuggestions() { 294d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka return hasMessages(MSG_UPDATE_SUGGESTIONS); 295d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 296d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 297d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void postUpdateOldSuggestions() { 298d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_OLD_SUGGESTIONS); 299d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_UPDATE_OLD_SUGGESTIONS), 3009b2192bfd2d3a06df3c685ed4287e192dbaabf32Ken Wakasa mConfigDelayUpdateOldSuggestions); 301d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 302d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 303d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void cancelUpdateOldSuggestions() { 304d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_OLD_SUGGESTIONS); 305d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 306d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 307d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void postUpdateShiftKeyState() { 308d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_SHIFT_STATE); 3099b2192bfd2d3a06df3c685ed4287e192dbaabf32Ken Wakasa sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE), mConfigDelayUpdateShiftState); 310d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 311d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 312d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void cancelUpdateShiftState() { 313d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_SHIFT_STATE); 314d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 315d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 316cb3320179d39a7983874697a0aa428b127675c9dJean Chalard public void postUpdateBigramPredictions() { 317cb3320179d39a7983874697a0aa428b127675c9dJean Chalard removeMessages(MSG_SET_BIGRAM_PREDICTIONS); 3189b2192bfd2d3a06df3c685ed4287e192dbaabf32Ken Wakasa sendMessageDelayed(obtainMessage(MSG_SET_BIGRAM_PREDICTIONS), 3199b2192bfd2d3a06df3c685ed4287e192dbaabf32Ken Wakasa mConfigDelayUpdateSuggestions); 32089bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 32189bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard 322cb3320179d39a7983874697a0aa428b127675c9dJean Chalard public void cancelUpdateBigramPredictions() { 323cb3320179d39a7983874697a0aa428b127675c9dJean Chalard removeMessages(MSG_SET_BIGRAM_PREDICTIONS); 32489bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 32589bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard 326d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void updateVoiceResults() { 327d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka sendMessage(obtainMessage(MSG_VOICE_RESULTS)); 328d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 329de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka 330d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka public void startDisplayLanguageOnSpacebar(boolean localeChanged) { 331de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka removeMessages(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR); 332de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka removeMessages(MSG_DISMISS_LANGUAGE_ON_SPACEBAR); 333de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka final LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); 334de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (inputView != null) { 335050c0462dc2ada5a5afecec5b6745693c5066b85Tadashi G. Takaoka final LatinKeyboard keyboard = mKeyboardSwitcher.getLatinKeyboard(); 336c5c57b506e97b334a394d23ed73c9597cb55707aTadashi G. Takaoka // The language is always displayed when the delay is negative. 337c5c57b506e97b334a394d23ed73c9597cb55707aTadashi G. Takaoka final boolean needsToDisplayLanguage = localeChanged 338c5c57b506e97b334a394d23ed73c9597cb55707aTadashi G. Takaoka || mConfigDelayBeforeFadeoutLanguageOnSpacebar < 0; 339de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka // The language is never displayed when the delay is zero. 340de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (mConfigDelayBeforeFadeoutLanguageOnSpacebar != 0) 341c5c57b506e97b334a394d23ed73c9597cb55707aTadashi G. Takaoka inputView.setSpacebarTextFadeFactor(needsToDisplayLanguage ? 1.0f 342d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka : mConfigFinalFadeoutFactorOfLanguageOnSpacebar, keyboard); 343c5c57b506e97b334a394d23ed73c9597cb55707aTadashi G. Takaoka // The fadeout animation will start when the delay is positive. 344d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka if (localeChanged && mConfigDelayBeforeFadeoutLanguageOnSpacebar > 0) { 345de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR, keyboard), 346de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka mConfigDelayBeforeFadeoutLanguageOnSpacebar); 347de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka } 348de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka } 349de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka } 350fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka 351fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka public void startDoubleSpacesTimer() { 352fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka removeMessages(MSG_SPACE_TYPED); 353fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_SPACE_TYPED), 354fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka mConfigDoubleSpacesTurnIntoPeriodTimeout); 355fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka } 356fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka 357fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka public void cancelDoubleSpacesTimer() { 358fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka removeMessages(MSG_SPACE_TYPED); 359fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka } 360fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka 361fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka public boolean isAcceptingDoubleSpaces() { 362fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka return hasMessages(MSG_SPACE_TYPED); 363fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka } 364d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 365923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 3667e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka @Override 3677e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka public void onCreate() { 36827d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); 36927d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa mPrefs = prefs; 37027d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa LatinImeLogger.init(this, prefs); 3716d9021527a38ba1e94225020389621a0d7227aa1satok LanguageSwitcherProxy.init(this, prefs); 37227d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa SubtypeSwitcher.init(this, prefs); 37327d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa KeyboardSwitcher.init(this, prefs); 374dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette AccessibilityUtils.init(this, prefs); 3757a8dac55278cedd838be325f56b4c52d973c61f5satok Recorrection.init(this, prefs); 376363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka 377923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onCreate(); 378363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka 379610f1dc8553cf2ed97e763a06a19380c4a6cd636satok mImm = InputMethodManagerCompatWrapper.getInstance(this); 3808efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka mInputMethodId = Utils.getInputMethodId(mImm, getPackageName()); 3810ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mSubtypeSwitcher = SubtypeSwitcher.getInstance(); 3820ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mKeyboardSwitcher = KeyboardSwitcher.getInstance(); 383dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette mAccessibilityUtils = AccessibilityUtils.getInstance(); 3847a8dac55278cedd838be325f56b4c52d973c61f5satok mRecorrection = Recorrection.getInstance(); 385363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka 386363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka final Resources res = getResources(); 387363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka mResources = res; 388fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard 3892fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka mConfigEnableShowSubtypeSettings = res.getBoolean( 3902fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka R.bool.config_enable_show_subtype_settings); 391363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka mConfigSwipeDownDismissKeyboardEnabled = res.getBoolean( 392363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka R.bool.config_swipe_down_dismiss_keyboard_enabled); 393de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka mConfigDelayBeforeFadeoutLanguageOnSpacebar = res.getInteger( 394de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka R.integer.config_delay_before_fadeout_language_on_spacebar); 3959b2192bfd2d3a06df3c685ed4287e192dbaabf32Ken Wakasa mConfigDelayUpdateSuggestions = res.getInteger(R.integer.config_delay_update_suggestions); 3969b2192bfd2d3a06df3c685ed4287e192dbaabf32Ken Wakasa mConfigDelayUpdateOldSuggestions = res.getInteger( 3979b2192bfd2d3a06df3c685ed4287e192dbaabf32Ken Wakasa R.integer.config_delay_update_old_suggestions); 3989b2192bfd2d3a06df3c685ed4287e192dbaabf32Ken Wakasa mConfigDelayUpdateShiftState = res.getInteger(R.integer.config_delay_update_shift_state); 399de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka mConfigDurationOfFadeoutLanguageOnSpacebar = res.getInteger( 400de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka R.integer.config_duration_of_fadeout_language_on_spacebar); 401d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka mConfigFinalFadeoutFactorOfLanguageOnSpacebar = res.getInteger( 40266432cfc9b7680a653bcf19d0d4250db21155eceTadashi G. Takaoka R.integer.config_final_fadeout_percentage_of_language_on_spacebar) / 100.0f; 403fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka mConfigDoubleSpacesTurnIntoPeriodTimeout = res.getInteger( 404fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka R.integer.config_double_spaces_turn_into_period_timeout); 405979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 4069502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka Utils.GCUtils.getInstance().reset(); 407979f8690967ff5409fe18f5085858ccdb8e0ccf1satok boolean tryGC = true; 4089502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) { 409979f8690967ff5409fe18f5085858ccdb8e0ccf1satok try { 4100ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok initSuggest(); 411979f8690967ff5409fe18f5085858ccdb8e0ccf1satok tryGC = false; 412979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } catch (OutOfMemoryError e) { 4139502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka tryGC = Utils.GCUtils.getInstance().tryGCOrWait("InitSuggest", e); 414979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 415979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 416979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 417363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka mOrientation = res.getConfiguration().orientation; 4186a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani initSuggestPuncList(); 419b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani 420cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard // Register to receive ringer mode change and network state change. 421cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard // Also receive installation and removal of a dictionary pack. 422123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka final IntentFilter filter = new IntentFilter(); 423123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); 424123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 425923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project registerReceiver(mReceiver, filter); 426b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy = VoiceProxy.init(this, prefs, mHandler); 427cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard 428cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard final IntentFilter packageFilter = new IntentFilter(); 429cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 430cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 431cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard packageFilter.addDataScheme(SCHEME_PACKAGE); 432cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard registerReceiver(mDictionaryPackInstallReceiver, packageFilter); 433646d950ed8d2b2555df92855e18b350fd7761b21Jean Chalard 434646d950ed8d2b2555df92855e18b350fd7761b21Jean Chalard final IntentFilter newDictFilter = new IntentFilter(); 435646d950ed8d2b2555df92855e18b350fd7761b21Jean Chalard newDictFilter.addAction( 436646d950ed8d2b2555df92855e18b350fd7761b21Jean Chalard DictionaryPackInstallBroadcastReceiver.NEW_DICTIONARY_INTENT_ACTION); 437646d950ed8d2b2555df92855e18b350fd7761b21Jean Chalard registerReceiver(mDictionaryPackInstallReceiver, newDictFilter); 438923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 43936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 4400ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private void initSuggest() { 441cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard final String localeStr = mSubtypeSwitcher.getInputLocaleStr(); 442cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard final Locale keyboardLocale = new Locale(localeStr); 44336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 444309bff562fbaf47488e6bf6636840f00574187d8Jean Chalard final Resources res = mResources; 445309bff562fbaf47488e6bf6636840f00574187d8Jean Chalard final Locale savedLocale = Utils.setSystemLocale(res, keyboardLocale); 44636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani if (mSuggest != null) { 44736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani mSuggest.close(); 44836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 44927d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa final SharedPreferences prefs = mPrefs; 45089764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard mQuickFixes = isQuickFixesEnabled(prefs); 451979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 4528efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka int mainDicResId = Utils.getMainDictionaryResourceId(res); 453cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard mSuggest = new Suggest(this, mainDicResId, keyboardLocale); 4541b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka loadAndSetAutoCorrectionThreshold(prefs); 45527023341658b4cf5430d18ddb94fd9502ecfe3cbTadashi G. Takaoka updateAutoTextEnabled(); 456e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 457cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard mUserDictionary = new UserDictionary(this, localeStr); 458923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSuggest.setUserDictionary(mUserDictionary); 459e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 460e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mContactsDictionary = new ContactsDictionary(this, Suggest.DIC_CONTACTS); 4612bed1531c2c9bd48096bfa97dd1a39e04bd15e7bEric Fischer mSuggest.setContactsDictionary(mContactsDictionary); 462e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 463cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard mAutoDictionary = new AutoDictionary(this, this, localeStr, Suggest.DIC_AUTO); 46434386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani mSuggest.setAutoDictionary(mAutoDictionary); 465e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 466cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard mUserBigramDictionary = new UserBigramDictionary(this, this, localeStr, Suggest.DIC_USER); 467e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mSuggest.setUserBigramDictionary(mUserBigramDictionary); 468e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 469e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani updateCorrectionMode(); 470863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard mMagicSpaceStrippers = res.getString(R.string.magic_space_stripping_symbols); 471863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard mMagicSpaceSwappers = res.getString(R.string.magic_space_swapping_symbols); 472863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard String wordSeparators = mMagicSpaceStrippers + mMagicSpaceSwappers 473863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard + res.getString(R.string.magic_space_promoting_symbols); 474863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard final String notWordSeparators = res.getString(R.string.non_word_separator_symbols); 475863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard for (int i = notWordSeparators.length() - 1; i >= 0; --i) 476863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard wordSeparators = wordSeparators.replace(notWordSeparators.substring(i, i + 1), ""); 477863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard mWordSeparators = wordSeparators; 47836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 479309bff562fbaf47488e6bf6636840f00574187d8Jean Chalard Utils.setSystemLocale(res, savedLocale); 480923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 48136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 482cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard /* package private */ void resetSuggestMainDict() { 483cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard final String localeStr = mSubtypeSwitcher.getInputLocaleStr(); 484cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard final Locale keyboardLocale = new Locale(localeStr); 485cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard int mainDicResId = Utils.getMainDictionaryResourceId(mResources); 486cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard mSuggest.resetMainDict(this, mainDicResId, keyboardLocale); 487cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard } 488cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard 489466741d8a78965b8509bf527344f289e50873092Mike LeBeau @Override 490466741d8a78965b8509bf527344f289e50873092Mike LeBeau public void onDestroy() { 491e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa if (mSuggest != null) { 492e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mSuggest.close(); 493e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mSuggest = null; 494979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 495923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project unregisterReceiver(mReceiver); 496cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard unregisterReceiver(mDictionaryPackInstallReceiver); 497b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.destroy(); 498979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.commit(); 499979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.onDestroy(); 500923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onDestroy(); 501923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 502923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 503923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 504923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onConfigurationChanged(Configuration conf) { 505dc64b138b5e3fb3706c0818d0a308fe6e36985b0Tadashi G. Takaoka mSubtypeSwitcher.onConfigurationChanged(conf); 506b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani // If orientation changed while predicting, commit the change 507b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani if (conf.orientation != mOrientation) { 508466741d8a78965b8509bf527344f289e50873092Mike LeBeau InputConnection ic = getCurrentInputConnection(); 509466741d8a78965b8509bf527344f289e50873092Mike LeBeau commitTyped(ic); 510466741d8a78965b8509bf527344f289e50873092Mike LeBeau if (ic != null) ic.finishComposingText(); // For voice input 511b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani mOrientation = conf.orientation; 5122fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka if (isShowingOptionDialog()) 5132fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka mOptionsDialog.dismiss(); 514b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani } 5158b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka 51681c52293f84ce475ac6b1661f4a4b92703405247Amith Yamasani mConfigurationChanging = true; 517923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onConfigurationChanged(conf); 518b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.onConfigurationChanged(conf); 51981c52293f84ce475ac6b1661f4a4b92703405247Amith Yamasani mConfigurationChanging = false; 52088fc9d44186120f9edc5cf7ec0e2af85260fed04satok 52188fc9d44186120f9edc5cf7ec0e2af85260fed04satok // This will work only when the subtype is not supported. 52288fc9d44186120f9edc5cf7ec0e2af85260fed04satok LanguageSwitcherProxy.onConfigurationChanged(conf); 523923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 524b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani 525923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 526923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public View onCreateInputView() { 5278d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka return mKeyboardSwitcher.onCreateInputView(); 528923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 529923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 530923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 531923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public View onCreateCandidatesView() { 532e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka LayoutInflater inflater = getLayoutInflater(); 533e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka LinearLayout container = (LinearLayout)inflater.inflate(R.layout.candidates, null); 534e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka mCandidateViewContainer = container; 5357a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka mCandidateStripHeight = (int)mResources.getDimension(R.dimen.candidate_strip_height); 536e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka mCandidateView = (CandidateView) container.findViewById(R.id.candidates); 537923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCandidateView.setService(this); 538923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project setCandidatesViewShown(true); 539e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka return container; 540923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 541923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 542a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker @Override 543923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onStartInputView(EditorInfo attribute, boolean restarting) { 54445911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final KeyboardSwitcher switcher = mKeyboardSwitcher; 54545911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka LatinKeyboardView inputView = switcher.getInputView(); 5468e09172df1bb176cc899940862c56bed9b9aec4esatok 54789bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (DEBUG) { 548910b73127fa207dd26ec8124000262523b0aac0csatok Log.d(TAG, "onStartInputView: " + inputView); 549910b73127fa207dd26ec8124000262523b0aac0csatok } 550923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // In landscape mode, this method gets called without the input view being created. 551979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (inputView == null) { 552923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 553923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 554923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 5558d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka mSubtypeSwitcher.updateParametersOnStartInputView(); 5564ab730dbd34fad323063f2ffd31ce33de746668dsatok 557662bb7c26cadd5026cb3d4e5d081aae163bd5a3aTadashi G. Takaoka TextEntryState.reset(); 5586c7c8f5b477e7aea207d41417092e8b92db2e24fAmith Yamasani 559c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // Most such things we decide below in initializeInputAttributesAndGetMode, but we need to 560c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // know now whether this is a password text field, because we need to know now whether we 561c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // want to enable the voice button. 562b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok final VoiceProxy voiceIme = mVoiceProxy; 563e9957752bcaad048746c7a57bbd2c0a59e1918a0satok voiceIme.resetVoiceStates(InputTypeCompatUtils.isPasswordInputType(attribute.inputType) 564e9957752bcaad048746c7a57bbd2c0a59e1918a0satok || InputTypeCompatUtils.isVisiblePasswordInputType(attribute.inputType)); 565c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 566cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka initializeInputAttributes(attribute); 567c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 568c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka inputView.closing(); 569c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mEnteredText = null; 570c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mComposing.setLength(0); 571f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard mHasUncommittedTypedChars = false; 572c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mDeleteCount = 0; 5730730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard mJustAddedMagicSpace = false; 574c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 575c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka loadSettings(attribute); 576c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka if (mSubtypeSwitcher.isKeyboardMode()) { 577cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka switcher.loadKeyboard(attribute, 5784503e2ea9853c1573f60903d8639d82e39e07c56Tadashi G. Takaoka mSubtypeSwitcher.isShortcutImeEnabled() && voiceIme.isVoiceButtonEnabled(), 5794503e2ea9853c1573f60903d8639d82e39e07c56Tadashi G. Takaoka voiceIme.isVoiceButtonOnPrimary()); 580c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka switcher.updateShiftState(); 581c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka } 582c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 5837a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka setCandidatesViewShownInternal(isCandidateStripVisible(), false /* needsInputViewShown */ ); 584c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // Delay updating suggestions because keyboard input view may not be shown at this point. 585c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mHandler.postUpdateSuggestions(); 586c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 587c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka updateCorrectionMode(); 588c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 589dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette final boolean accessibilityEnabled = mAccessibilityUtils.isAccessibilityEnabled(); 590dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette 591d9786ce2e389c8c02af7773b53b5c44fe4fa0b0cTadashi G. Takaoka inputView.setKeyPreviewEnabled(mPopupOn); 592c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka inputView.setProximityCorrectionEnabled(true); 593dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette inputView.setAccessibilityEnabled(accessibilityEnabled); 594c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // If we just entered a text field, maybe it has some old text that requires correction 5957a8dac55278cedd838be325f56b4c52d973c61f5satok mRecorrection.checkRecorrectionOnStart(); 596c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka inputView.setForeground(true); 597c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 5984503e2ea9853c1573f60903d8639d82e39e07c56Tadashi G. Takaoka voiceIme.onStartInputView(inputView.getWindowToken()); 599c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 600c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); 601c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka } 602c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 603cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka private void initializeInputAttributes(EditorInfo attribute) { 604cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka if (attribute == null) 605cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka return; 6064b13b4f94215368c6387b2564bdaf2cbcbe4c130Tadashi G. Takaoka final int inputType = attribute.inputType; 607c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka final int variation = inputType & InputType.TYPE_MASK_VARIATION; 6080730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard mShouldInsertMagicSpace = false; 609e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mInputTypeNoAutoCorrect = false; 6109fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 6111b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mApplicationSpecifiedCompletionOn = false; 6121b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mApplicationSpecifiedCompletions = null; 613dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani 614cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka if ((inputType & InputType.TYPE_MASK_CLASS) == InputType.TYPE_CLASS_TEXT) { 615cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mIsSettingsSuggestionStripOn = true; 616cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka // Make sure that passwords are not displayed in candidate view 617e9957752bcaad048746c7a57bbd2c0a59e1918a0satok if (InputTypeCompatUtils.isPasswordInputType(inputType) 618e9957752bcaad048746c7a57bbd2c0a59e1918a0satok || InputTypeCompatUtils.isVisiblePasswordInputType(inputType)) { 619cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 620cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } 621e9957752bcaad048746c7a57bbd2c0a59e1918a0satok if (InputTypeCompatUtils.isEmailVariation(variation) 622cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka || variation == InputType.TYPE_TEXT_VARIATION_PERSON_NAME) { 6230730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard mShouldInsertMagicSpace = false; 624cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } else { 6250730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard mShouldInsertMagicSpace = true; 626cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } 627e9957752bcaad048746c7a57bbd2c0a59e1918a0satok if (InputTypeCompatUtils.isEmailVariation(variation)) { 628cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 629cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } else if (variation == InputType.TYPE_TEXT_VARIATION_URI) { 630cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 631cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) { 632cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 633cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } else if (variation == InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) { 634cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka // If it's a browser edit field and auto correct is not ON explicitly, then 635cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka // disable auto correction, but keep suggestions on. 636cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) { 637e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mInputTypeNoAutoCorrect = true; 63836ebae2e8d58d36d3f8dd2f8a2d34c0c06522a8eAmith Yamasani } 639cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } 640cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka 641cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka // If NO_SUGGESTIONS is set, don't do prediction. 642cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka if ((inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) { 643cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 644cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mInputTypeNoAutoCorrect = true; 645cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } 646cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka // If it's not multiline and the autoCorrect flag is not set, then don't correct 647cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 648cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka && (inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) == 0) { 649cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mInputTypeNoAutoCorrect = true; 650cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } 651cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) { 652cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 653cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mApplicationSpecifiedCompletionOn = isFullscreenMode(); 654cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } 655923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 656923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 657923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 658923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 659923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onFinishInput() { 660923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onFinishInput(); 661a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 662979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.commit(); 6631b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mKeyboardSwitcher.onAutoCorrectionStateChanged(false); 664979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 665b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.flushVoiceInputLogs(mConfigurationChanging); 666409220583333bdf06290dd9fd42f91b5c0d1b11asatok 6675a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka KeyboardView inputView = mKeyboardSwitcher.getInputView(); 668d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa if (inputView != null) inputView.closing(); 6694ff60be170872503cca0275ef3488b7379b5311bAmith Yamasani if (mAutoDictionary != null) mAutoDictionary.flushPendingWrites(); 670979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mUserBigramDictionary != null) mUserBigramDictionary.flushPendingWrites(); 671466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 672466741d8a78965b8509bf527344f289e50873092Mike LeBeau 673466741d8a78965b8509bf527344f289e50873092Mike LeBeau @Override 6746495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa public void onFinishInputView(boolean finishingInput) { 6756495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa super.onFinishInputView(finishingInput); 6765a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka KeyboardView inputView = mKeyboardSwitcher.getInputView(); 677d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa if (inputView != null) inputView.setForeground(false); 678d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka // Remove pending messages related to update suggestions 679d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.cancelUpdateSuggestions(); 680d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.cancelUpdateOldSuggestions(); 6816495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa } 6826495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa 6836495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa @Override 684466741d8a78965b8509bf527344f289e50873092Mike LeBeau public void onUpdateExtractedText(int token, ExtractedText text) { 685466741d8a78965b8509bf527344f289e50873092Mike LeBeau super.onUpdateExtractedText(token, text); 686b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.showPunctuationHintIfNecessary(); 687923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 688923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 689923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 690923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onUpdateSelection(int oldSelStart, int oldSelEnd, 691923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int newSelStart, int newSelEnd, 692923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int candidatesStart, int candidatesEnd) { 693923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, 694923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project candidatesStart, candidatesEnd); 695466741d8a78965b8509bf527344f289e50873092Mike LeBeau 696466741d8a78965b8509bf527344f289e50873092Mike LeBeau if (DEBUG) { 697466741d8a78965b8509bf527344f289e50873092Mike LeBeau Log.i(TAG, "onUpdateSelection: oss=" + oldSelStart 698466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", ose=" + oldSelEnd 699025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa + ", lss=" + mLastSelectionStart 700025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa + ", lse=" + mLastSelectionEnd 701466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", nss=" + newSelStart 702466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", nse=" + newSelEnd 703466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", cs=" + candidatesStart 704466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", ce=" + candidatesEnd); 705466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 706466741d8a78965b8509bf527344f289e50873092Mike LeBeau 707b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.setCursorAndSelection(newSelEnd, newSelStart); 7084f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 709923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // If the current selection in the text view changes, we should 710923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // clear whatever candidate text we have. 711025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa final boolean selectionChanged = (newSelStart != candidatesEnd 712025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa || newSelEnd != candidatesEnd) && mLastSelectionStart != newSelStart; 713025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa final boolean candidatesCleared = candidatesStart == -1 && candidatesEnd == -1; 714f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard if (((mComposing.length() > 0 && mHasUncommittedTypedChars) 715b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok || mVoiceProxy.isVoiceInputHighlighted()) 716025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa && (selectionChanged || candidatesCleared)) { 717025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa if (candidatesCleared) { 718025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa // If the composing span has been cleared, save the typed word in the history for 719025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa // recorrection before we reset the candidate strip. Then, we'll be able to show 720025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa // suggestions for recorrection right away. 721f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok mRecorrection.saveRecorrectionSuggestion(mWord, mComposing); 722025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa } 723923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mComposing.setLength(0); 724f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard mHasUncommittedTypedChars = false; 72589bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (isCursorTouchingWord()) { 726cb3320179d39a7983874697a0aa428b127675c9dJean Chalard mHandler.cancelUpdateBigramPredictions(); 72789bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard mHandler.postUpdateSuggestions(); 72889bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } else { 72989bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard setPunctuationSuggestions(); 73089bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 731923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.reset(); 732923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 733923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 734923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.finishComposingText(); 735923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 736b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.setVoiceInputHighlighted(false); 737f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard } else if (!mHasUncommittedTypedChars && !mJustAccepted) { 738662bb7c26cadd5026cb3d4e5d081aae163bd5a3aTadashi G. Takaoka if (TextEntryState.isAcceptedDefault() || TextEntryState.isSpaceAfterPicked()) { 739662bb7c26cadd5026cb3d4e5d081aae163bd5a3aTadashi G. Takaoka if (TextEntryState.isAcceptedDefault()) 740662bb7c26cadd5026cb3d4e5d081aae163bd5a3aTadashi G. Takaoka TextEntryState.reset(); 7410730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard mJustAddedMagicSpace = false; // The user moved the cursor. 7429a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 743923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 744923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mJustAccepted = false; 745d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateShiftKeyState(); 746466741d8a78965b8509bf527344f289e50873092Mike LeBeau 747979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Make a note of the cursor position 748979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mLastSelectionStart = newSelStart; 749979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mLastSelectionEnd = newSelEnd; 750466741d8a78965b8509bf527344f289e50873092Mike LeBeau 7517a8dac55278cedd838be325f56b4c52d973c61f5satok mRecorrection.updateRecorrectionSelection(mKeyboardSwitcher, 7527a8dac55278cedd838be325f56b4c52d973c61f5satok mCandidateView, candidatesStart, candidatesEnd, newSelStart, 7537a8dac55278cedd838be325f56b4c52d973c61f5satok newSelEnd, oldSelStart, mLastSelectionStart, 7547a8dac55278cedd838be325f56b4c52d973c61f5satok mLastSelectionEnd, mHasUncommittedTypedChars); 7557a8dac55278cedd838be325f56b4c52d973c61f5satok } 7567a8dac55278cedd838be325f56b4c52d973c61f5satok 7577a8dac55278cedd838be325f56b4c52d973c61f5satok public void setLastSelection(int start, int end) { 7587a8dac55278cedd838be325f56b4c52d973c61f5satok mLastSelectionStart = start; 7597a8dac55278cedd838be325f56b4c52d973c61f5satok mLastSelectionEnd = end; 760923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 761923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 762c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani /** 763c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * This is called when the user has clicked on the extracted text view, 764c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * when running in fullscreen mode. The default implementation hides 765c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * the candidates view when this happens, but only if the extracted text 766c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * editor has a vertical scroll bar because its text doesn't fit. 767c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * Here we override the behavior due to the possibility that a re-correction could 768c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * cause the candidate strip to disappear and re-appear. 769c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani */ 770c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani @Override 771c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani public void onExtractedTextClicked() { 7727a8dac55278cedd838be325f56b4c52d973c61f5satok if (mRecorrection.isRecorrectionEnabled() && isSuggestionsRequested()) return; 773c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 774c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani super.onExtractedTextClicked(); 775c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani } 776c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 777c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani /** 778c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * This is called when the user has performed a cursor movement in the 779c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * extracted text view, when it is running in fullscreen mode. The default 780c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * implementation hides the candidates view when a vertical movement 781c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * happens, but only if the extracted text editor has a vertical scroll bar 782c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * because its text doesn't fit. 783c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * Here we override the behavior due to the possibility that a re-correction could 784c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * cause the candidate strip to disappear and re-appear. 785c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani */ 786c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani @Override 787c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani public void onExtractedCursorMovement(int dx, int dy) { 7887a8dac55278cedd838be325f56b4c52d973c61f5satok if (mRecorrection.isRecorrectionEnabled() && isSuggestionsRequested()) return; 789c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 790c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani super.onExtractedCursorMovement(dx, dy); 791c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani } 792c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 793923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 794923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void hideWindow() { 795979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.commit(); 7961b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mKeyboardSwitcher.onAutoCorrectionStateChanged(false); 797979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 798923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (TRACE) Debug.stopMethodTracing(); 7996e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani if (mOptionsDialog != null && mOptionsDialog.isShowing()) { 8006e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani mOptionsDialog.dismiss(); 8016e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani mOptionsDialog = null; 8026e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani } 803b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.hideVoiceWindow(mConfigurationChanging); 8049fbfd5877305ed19a20663630b498b6b3fdae942satok mRecorrection.clearWordsInHistory(); 805923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.hideWindow(); 806923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 807923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 808923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 8091b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka public void onDisplayCompletions(CompletionInfo[] applicationSpecifiedCompletions) { 810979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (DEBUG) { 811a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa Log.i(TAG, "Received completions:"); 812bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok if (applicationSpecifiedCompletions != null) { 813bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok for (int i = 0; i < applicationSpecifiedCompletions.length; i++) { 814bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok Log.i(TAG, " #" + i + ": " + applicationSpecifiedCompletions[i]); 815bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok } 816923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 817923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 8181b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka if (mApplicationSpecifiedCompletionOn) { 8191b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mApplicationSpecifiedCompletions = applicationSpecifiedCompletions; 8201b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka if (applicationSpecifiedCompletions == null) { 821b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani clearSuggestions(); 822923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 823923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 824a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 8257e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords.Builder builder = new SuggestedWords.Builder() 8261b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka .setApplicationSpecifiedCompletions(applicationSpecifiedCompletions) 8277e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka .setTypedWordValid(true) 8287e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka .setHasMinimalSuggestion(true); 829979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // When in fullscreen mode, show completions generated by the application 8307e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka setSuggestions(builder.build()); 831923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mBestWord = null; 832543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa setCandidatesViewShown(true); 833923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 834923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 835923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 836543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa private void setCandidatesViewShownInternal(boolean shown, boolean needsInputViewShown) { 8377a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka // TODO: Modify this if we support candidates with hard keyboard 838923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (onEvaluateInputViewShown()) { 8397a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka final boolean shouldShowCandidates = shown 8407a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true); 8417a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka if (isExtractViewShown()) { 8427a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka // No need to have extra space to show the key preview. 8437a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka mCandidateViewContainer.setMinimumHeight(0); 8447a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka super.setCandidatesViewShown(shown); 8457a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka } else { 8467a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka // We must control the visibility of the suggestion strip in order to avoid clipped 8477a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka // key previews, even when we don't show the suggestion strip. 8487a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka mCandidateViewContainer.setVisibility( 8497a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka shouldShowCandidates ? View.VISIBLE : View.INVISIBLE); 8507a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka super.setCandidatesViewShown(true); 8517a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka } 852923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 853923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 854a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 855923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 856543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa public void setCandidatesViewShown(boolean shown) { 857543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa setCandidatesViewShownInternal(shown, true /* needsInputViewShown */ ); 858543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa } 859543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa 860543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa @Override 861923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onComputeInsets(InputMethodService.Insets outInsets) { 862923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onComputeInsets(outInsets); 8637a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka final KeyboardView inputView = mKeyboardSwitcher.getInputView(); 86446ca84584810dfe606e709b3fe283cbde8aba5f5Tadashi G. Takaoka if (inputView == null) 86546ca84584810dfe606e709b3fe283cbde8aba5f5Tadashi G. Takaoka return; 86646ca84584810dfe606e709b3fe283cbde8aba5f5Tadashi G. Takaoka final int containerHeight = mCandidateViewContainer.getHeight(); 86746ca84584810dfe606e709b3fe283cbde8aba5f5Tadashi G. Takaoka int touchY = containerHeight; 8689e347d3d448e48229c46aad394ec9bd60cd5807bsatok // Need to set touchable region only if input view is being shown 86946ca84584810dfe606e709b3fe283cbde8aba5f5Tadashi G. Takaoka if (mKeyboardSwitcher.isInputViewShown()) { 8707a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka if (mCandidateViewContainer.getVisibility() == View.VISIBLE) { 8717a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka touchY -= mCandidateStripHeight; 8729e347d3d448e48229c46aad394ec9bd60cd5807bsatok } 8737a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka final int touchWidth = inputView.getWidth(); 8747a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka final int touchHeight = inputView.getHeight() + containerHeight 8757a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka // Extend touchable region below the keyboard. 8767a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka + EXTENDED_TOUCHABLE_REGION_HEIGHT; 8779e347d3d448e48229c46aad394ec9bd60cd5807bsatok if (DEBUG) { 8787a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka Log.d(TAG, "Touchable region: y=" + touchY + " width=" + touchWidth 8797a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka + " height=" + touchHeight); 8809e347d3d448e48229c46aad394ec9bd60cd5807bsatok } 8817a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka setTouchableRegionCompat(outInsets, 0, touchY, touchWidth, touchHeight); 8829e347d3d448e48229c46aad394ec9bd60cd5807bsatok } 88346ca84584810dfe606e709b3fe283cbde8aba5f5Tadashi G. Takaoka outInsets.contentTopInsets = touchY; 88446ca84584810dfe606e709b3fe283cbde8aba5f5Tadashi G. Takaoka outInsets.visibleTopInsets = touchY; 885923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 886a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 887923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 888979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public boolean onEvaluateFullscreenMode() { 889458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa final Resources res = mResources; 890458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa DisplayMetrics dm = res.getDisplayMetrics(); 891979f8690967ff5409fe18f5085858ccdb8e0ccf1satok float displayHeight = dm.heightPixels; 892979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // If the display is more than X inches high, don't go to fullscreen mode 893458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa float dimen = res.getDimension(R.dimen.max_height_for_fullscreen); 894979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (displayHeight > dimen) { 895979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return false; 896979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } else { 897979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return super.onEvaluateFullscreenMode(); 898979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 899979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 900979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 901979f8690967ff5409fe18f5085858ccdb8e0ccf1satok @Override 902923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 903923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (keyCode) { 904e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_BACK: 905e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (event.getRepeatCount() == 0 && mKeyboardSwitcher.getInputView() != null) { 906e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (mKeyboardSwitcher.getInputView().handleBack()) { 9076e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani return true; 9086e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani } 909e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } 910e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka break; 911923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 912923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return super.onKeyDown(keyCode, event); 913923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 914923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 915923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 916923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean onKeyUp(int keyCode, KeyEvent event) { 917923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (keyCode) { 918e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_DPAD_DOWN: 919e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_DPAD_UP: 920e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_DPAD_LEFT: 921e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_DPAD_RIGHT: 922e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka // Enable shift key and DPAD to do selections 923e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (mKeyboardSwitcher.isInputViewShown() 924e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka && mKeyboardSwitcher.isShiftedOrShiftLocked()) { 925e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka KeyEvent newEvent = new KeyEvent(event.getDownTime(), event.getEventTime(), 926e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka event.getAction(), event.getKeyCode(), event.getRepeatCount(), 927e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka event.getDeviceId(), event.getScanCode(), 928e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON); 929e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka InputConnection ic = getCurrentInputConnection(); 930e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (ic != null) 931e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka ic.sendKeyEvent(newEvent); 932e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka return true; 933e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } 934e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka break; 935923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 936923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return super.onKeyUp(keyCode, event); 937923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 938923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 939409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void commitTyped(InputConnection inputConnection) { 940f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard if (mHasUncommittedTypedChars) { 941f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard mHasUncommittedTypedChars = false; 942923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mComposing.length() > 0) { 943923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (inputConnection != null) { 944923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project inputConnection.commitText(mComposing, 1); 945923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 946923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCommittedLength = mComposing.length(); 947923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.acceptedTyped(mComposing); 948bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok addToAutoAndUserBigramDictionaries(mComposing, AutoDictionary.FREQUENCY_FOR_TYPED); 949923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 950923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project updateSuggestions(); 951923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 952923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 953923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 954b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka public boolean getCurrentAutoCapsState() { 955923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 9561c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani EditorInfo ei = getCurrentInputEditorInfo(); 957e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (mAutoCap && ic != null && ei != null && ei.inputType != InputType.TYPE_NULL) { 958b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return ic.getCursorCapsMode(ei.inputType) != 0; 9591c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani } 960b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return false; 9611c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani } 9621c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani 963863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard private void swapSwapperAndSpace() { 964923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final InputConnection ic = getCurrentInputConnection(); 965923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic == null) return; 966923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence lastTwo = ic.getTextBeforeCursor(2, 0); 967863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard // It is guaranteed lastTwo.charAt(1) is a swapper - else this method is not called. 968923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (lastTwo != null && lastTwo.length() == 2 969863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard && lastTwo.charAt(0) == Keyboard.CODE_SPACE) { 970923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.beginBatchEdit(); 971923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.deleteSurroundingText(2, 0); 972923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.commitText(lastTwo.charAt(1) + " ", 1); 973923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.endBatchEdit(); 974b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 9754ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa } 9764ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa } 9774ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa 978863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard private void maybeDoubleSpace() { 979923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mCorrectionMode == Suggest.CORRECTION_NONE) return; 980923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final InputConnection ic = getCurrentInputConnection(); 981923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic == null) return; 982923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence lastThree = ic.getTextBeforeCursor(3, 0); 983923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (lastThree != null && lastThree.length() == 3 984923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project && Character.isLetterOrDigit(lastThree.charAt(0)) 985571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastThree.charAt(1) == Keyboard.CODE_SPACE 986fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka && lastThree.charAt(2) == Keyboard.CODE_SPACE 987fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka && mHandler.isAcceptingDoubleSpaces()) { 988fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka mHandler.cancelDoubleSpacesTimer(); 989923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.beginBatchEdit(); 990923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.deleteSurroundingText(2, 0); 991923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.commitText(". ", 1); 992923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.endBatchEdit(); 993b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 994fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka } else { 995fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka mHandler.startDoubleSpacesTimer(); 996923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 997923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 998a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 99941a519729505a877844f2c57a33509c302dddbceKen Wakasa private void maybeRemovePreviousPeriod(CharSequence text) { 100041a519729505a877844f2c57a33509c302dddbceKen Wakasa final InputConnection ic = getCurrentInputConnection(); 100141a519729505a877844f2c57a33509c302dddbceKen Wakasa if (ic == null) return; 100241a519729505a877844f2c57a33509c302dddbceKen Wakasa 100341a519729505a877844f2c57a33509c302dddbceKen Wakasa // When the text's first character is '.', remove the previous period 100441a519729505a877844f2c57a33509c302dddbceKen Wakasa // if there is one. 100541a519729505a877844f2c57a33509c302dddbceKen Wakasa CharSequence lastOne = ic.getTextBeforeCursor(1, 0); 10064ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa if (lastOne != null && lastOne.length() == 1 1007571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastOne.charAt(0) == Keyboard.CODE_PERIOD 1008571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && text.charAt(0) == Keyboard.CODE_PERIOD) { 100941a519729505a877844f2c57a33509c302dddbceKen Wakasa ic.deleteSurroundingText(1, 0); 101041a519729505a877844f2c57a33509c302dddbceKen Wakasa } 101141a519729505a877844f2c57a33509c302dddbceKen Wakasa } 101241a519729505a877844f2c57a33509c302dddbceKen Wakasa 10139a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa private void removeTrailingSpace() { 10149a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa final InputConnection ic = getCurrentInputConnection(); 10159a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic == null) return; 10169a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa 10179a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa CharSequence lastOne = ic.getTextBeforeCursor(1, 0); 10189a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (lastOne != null && lastOne.length() == 1 1019571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastOne.charAt(0) == Keyboard.CODE_SPACE) { 10209a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.deleteSurroundingText(1, 0); 10219a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 10229a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 10239a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa 1024923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean addWordToDictionary(String word) { 1025923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mUserDictionary.addWord(word, 128); 10266558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // Suggestion strip should be updated after the operation of adding word to the 10276558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // user dictionary 1028d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 1029923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 1030923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1031923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1032923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean isAlphabet(int code) { 1033923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (Character.isLetter(code)) { 1034923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 1035923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1036923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return false; 1037923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1038923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1039a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1040e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka private void onSettingsKeyPressed() { 10419a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok if (!isShowingOptionDialog()) { 10422fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka if (!mConfigEnableShowSubtypeSettings) { 10432fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka showSubtypeSelectorAndSettings(); 10442fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } else if (Utils.hasMultipleEnabledIMEsOrSubtypes(mImm)) { 10459a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok showOptionsMenu(); 10469a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } else { 10479a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok launchSettings(); 10489a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10499a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10509a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10519a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok 1052e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka private void onSettingsKeyLongPressed() { 10539a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok if (!isShowingOptionDialog()) { 10549502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka if (Utils.hasMultipleEnabledIMEsOrSubtypes(mImm)) { 105579efbed76f638be298493107fa2d0cd1b5eb529esatok mImm.showInputMethodPicker(); 10569a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } else { 10579a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok launchSettings(); 10589a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10599a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10609a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10619a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok 10629a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok private boolean isShowingOptionDialog() { 10639a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok return mOptionsDialog != null && mOptionsDialog.isShowing(); 10649a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 10659a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok 10665f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka // Implementation of {@link KeyboardActionListener}. 10675a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 10688aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) { 1069923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project long when = SystemClock.uptimeMillis(); 1070571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (primaryCode != Keyboard.CODE_DELETE || when > mLastKeyTime + QUICK_PRESS) { 1071923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mDeleteCount = 0; 1072923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1073923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mLastKeyTime = when; 1074b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 1075dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette final boolean accessibilityEnabled = switcher.isAccessibilityEnabled(); 1076b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); 1077923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (primaryCode) { 1078571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_DELETE: 10794189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka handleBackspace(); 10804189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka mDeleteCount++; 10814189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka LatinImeLogger.logOnDelete(); 10824189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1083571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_SHIFT: 10844189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka // Shift key is handled in onPress() when device has distinct multi-touch panel. 1085dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette if (!distinctMultiTouch || accessibilityEnabled) 1086b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.toggleShift(); 10874189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1088e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka case Keyboard.CODE_SWITCH_ALPHA_SYMBOL: 10894189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka // Symbol key is handled in onPress() when device has distinct multi-touch panel. 1090dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette if (!distinctMultiTouch || accessibilityEnabled) 1091b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.changeKeyboardMode(); 10924189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1093571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_CANCEL: 10944189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka if (!isShowingOptionDialog()) { 10954189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka handleClose(); 10964189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka } 10974189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1098e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka case Keyboard.CODE_SETTINGS: 1099e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka onSettingsKeyPressed(); 11004189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1101e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka case Keyboard.CODE_SETTINGS_LONGPRESS: 1102e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka onSettingsKeyLongPressed(); 11034189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1104d2c5fdda862f6dd2a1e020cf674c35fbbc63fc92Tadashi G. Takaoka case LatinKeyboard.CODE_NEXT_LANGUAGE: 110588fc9d44186120f9edc5cf7ec0e2af85260fed04satok toggleLanguage(true); 11064189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1107d2c5fdda862f6dd2a1e020cf674c35fbbc63fc92Tadashi G. Takaoka case LatinKeyboard.CODE_PREV_LANGUAGE: 110888fc9d44186120f9edc5cf7ec0e2af85260fed04satok toggleLanguage(false); 11094189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1110571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_CAPSLOCK: 1111b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.toggleCapsLock(); 11124189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1113d2c5fdda862f6dd2a1e020cf674c35fbbc63fc92Tadashi G. Takaoka case Keyboard.CODE_SHORTCUT: 111420cdb37bd062ae6cb6d42ad6229a19733476cd55satok mSubtypeSwitcher.switchToShortcutIME(); 11154189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1116571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_TAB: 111745911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka handleTab(); 11184189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 11194189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka default: 11204189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka if (isWordSeparator(primaryCode)) { 1121b5d17e52fcda39d540822e615bfb7ed5074e0034satok handleSeparator(primaryCode, x, y); 11224189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka } else { 11238fbd55229243cb66c03d5ea1f79dfb39f596590dsatok handleCharacter(primaryCode, keyCodes, x, y); 11244189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka } 1125923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1126b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.onKey(primaryCode); 1127dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani // Reset after any single keystroke 1128dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani mEnteredText = null; 1129923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1130a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 11315a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 11328aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka public void onTextInput(CharSequence text) { 1133b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.commitVoiceInput(); 1134923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 1135923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic == null) return; 11369fbfd5877305ed19a20663630b498b6b3fdae942satok mRecorrection.abortRecorrection(false); 1137923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.beginBatchEdit(); 113855b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka commitTyped(ic); 113941a519729505a877844f2c57a33509c302dddbceKen Wakasa maybeRemovePreviousPeriod(text); 1140923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.commitText(text, 1); 1141923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.endBatchEdit(); 1142b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 11435f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka mKeyboardSwitcher.onKey(Keyboard.CODE_DUMMY); 11440730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard mJustAddedMagicSpace = false; 1145dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani mEnteredText = text; 1146923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1147923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 11485a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 11498aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka public void onCancelInput() { 115083e63ace2a1bd5b3c27d26d914456c2b0def17c5Tadashi G. Takaoka // User released a finger outside any key 11515f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka mKeyboardSwitcher.onCancelInput(); 115283e63ace2a1bd5b3c27d26d914456c2b0def17c5Tadashi G. Takaoka } 115383e63ace2a1bd5b3c27d26d914456c2b0def17c5Tadashi G. Takaoka 1154923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void handleBackspace() { 1155b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok if (mVoiceProxy.logAndRevertVoiceInput()) return; 11564f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1157504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka final InputConnection ic = getCurrentInputConnection(); 1158504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka if (ic == null) return; 1159979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ic.beginBatchEdit(); 1160979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1161b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.handleBackspace(); 11624f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1163504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka boolean deleteChar = false; 1164f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard if (mHasUncommittedTypedChars) { 1165923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int length = mComposing.length(); 1166923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (length > 0) { 1167923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mComposing.delete(length - 1, length); 1168923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mWord.deleteLast(); 1169923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.setComposingText(mComposing, 1); 1170923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mComposing.length() == 0) { 1171f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard mHasUncommittedTypedChars = false; 1172923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 117389bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (1 == length) { 117489bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // 1 == length means we are about to erase the last character of the word, 117589bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // so we can show bigrams. 1176cb3320179d39a7983874697a0aa428b127675c9dJean Chalard mHandler.postUpdateBigramPredictions(); 117789bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } else { 117889bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // length > 1, so we still have letters to deduce a suggestion from. 117989bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard mHandler.postUpdateSuggestions(); 118089bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 1181923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1182923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.deleteSurroundingText(1, 0); 1183923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1184923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1185923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project deleteChar = true; 1186923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1187d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateShiftKeyState(); 1188504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka 1189923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.backspace(); 1190662bb7c26cadd5026cb3d4e5d081aae163bd5a3aTadashi G. Takaoka if (TextEntryState.isUndoCommit()) { 1191923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project revertLastWord(deleteChar); 1192979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ic.endBatchEdit(); 1193923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1194504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka } 1195504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka 1196504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) { 1197dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani ic.deleteSurroundingText(mEnteredText.length(), 0); 1198923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else if (deleteChar) { 11996558253160e2039c87f424bd814f402ecd31de3bKen Wakasa if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) { 12006558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // Go back to the suggestion mode if the user canceled the 120155b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa // "Touch again to save". 12026558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // NOTE: In gerenal, we don't revert the word when backspacing 12036558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // from a manual suggestion pick. We deliberately chose a 12046558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // different behavior only in the case of picking the first 12056558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // suggestion (typed word). It's intentional to have made this 12066558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // inconsistent with backspacing after selecting other suggestions. 12076558253160e2039c87f424bd814f402ecd31de3bKen Wakasa revertLastWord(deleteChar); 12086558253160e2039c87f424bd814f402ecd31de3bKen Wakasa } else { 1209923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); 12106558253160e2039c87f424bd814f402ecd31de3bKen Wakasa if (mDeleteCount > DELETE_ACCELERATE_AT) { 12116558253160e2039c87f424bd814f402ecd31de3bKen Wakasa sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); 12126558253160e2039c87f424bd814f402ecd31de3bKen Wakasa } 1213923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1214923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1215979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ic.endBatchEdit(); 1216923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1217923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 121845911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka private void handleTab() { 121945911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final int imeOptions = getCurrentInputEditorInfo().imeOptions; 1220b2707856aba4fc9b063f26305f1fb603b19c1701satok if (!EditorInfoCompatUtils.hasFlagNavigateNext(imeOptions) 1221b2707856aba4fc9b063f26305f1fb603b19c1701satok && !EditorInfoCompatUtils.hasFlagNavigatePrevious(imeOptions)) { 122245911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka sendDownUpKeyEvents(KeyEvent.KEYCODE_TAB); 122345911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka return; 122445911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka } 122545911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka 122645911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final InputConnection ic = getCurrentInputConnection(); 122745911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka if (ic == null) 122845911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka return; 122945911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka 123045911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka // True if keyboard is in either chording shift or manual temporary upper case mode. 123145911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final boolean isManualTemporaryUpperCase = mKeyboardSwitcher.isManualTemporaryUpperCase(); 1232b2707856aba4fc9b063f26305f1fb603b19c1701satok if (EditorInfoCompatUtils.hasFlagNavigateNext(imeOptions) 123345911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka && !isManualTemporaryUpperCase) { 1234b2707856aba4fc9b063f26305f1fb603b19c1701satok EditorInfoCompatUtils.performEditorActionNext(ic); 123545911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka ic.performEditorAction(EditorInfo.IME_ACTION_NEXT); 1236b2707856aba4fc9b063f26305f1fb603b19c1701satok } else if (EditorInfoCompatUtils.hasFlagNavigatePrevious(imeOptions) 123745911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka && isManualTemporaryUpperCase) { 1238b2707856aba4fc9b063f26305f1fb603b19c1701satok EditorInfoCompatUtils.performEditorActionPrevious(ic); 123945911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka } 124045911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka } 124145911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka 12428fbd55229243cb66c03d5ea1f79dfb39f596590dsatok private void handleCharacter(int primaryCode, int[] keyCodes, int x, int y) { 1243b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.handleCharacter(); 12444f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1245863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard if (mJustAddedMagicSpace && isMagicSpaceStripper(primaryCode)) { 12460730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard removeTrailingSpace(); 12470730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard } 12480730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard 1249863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard if (mLastSelectionStart == mLastSelectionEnd) { 12509fbfd5877305ed19a20663630b498b6b3fdae942satok mRecorrection.abortRecorrection(false); 1251b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 12524f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1253e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka int code = primaryCode; 12549fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (isAlphabet(code) && isSuggestionsRequested() && !isCursorTouchingWord()) { 1255f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard if (!mHasUncommittedTypedChars) { 1256f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard mHasUncommittedTypedChars = true; 1257923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mComposing.setLength(0); 1258f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok mRecorrection.saveRecorrectionSuggestion(mWord, mBestWord); 1259923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mWord.reset(); 12607e99a28dfcc14f5b19220442db972ca8d786b4feKen Wakasa clearSuggestions(); 1261923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1262923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 12631679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 1264f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (switcher.isShiftedOrShiftLocked()) { 1265eef539c3f2b60af74a3ce05ac68288e7f86709aeAmith Yamasani if (keyCodes == null || keyCodes[0] < Character.MIN_CODE_POINT 1266eef539c3f2b60af74a3ce05ac68288e7f86709aeAmith Yamasani || keyCodes[0] > Character.MAX_CODE_POINT) { 1267eef539c3f2b60af74a3ce05ac68288e7f86709aeAmith Yamasani return; 1268eef539c3f2b60af74a3ce05ac68288e7f86709aeAmith Yamasani } 1269e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka code = keyCodes[0]; 1270e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (switcher.isAlphabetMode() && Character.isLowerCase(code)) { 1271e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka int upperCaseCode = Character.toUpperCase(code); 1272e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (upperCaseCode != code) { 1273e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka code = upperCaseCode; 127412a4e08a6440c95f29dc04efe83515a4ed045487Tadashi G. Takaoka } else { 127512a4e08a6440c95f29dc04efe83515a4ed045487Tadashi G. Takaoka // Some keys, such as [eszett], have upper case as multi-characters. 1276e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka String upperCase = new String(new int[] {code}, 0, 1).toUpperCase(); 12778aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka onTextInput(upperCase); 127812a4e08a6440c95f29dc04efe83515a4ed045487Tadashi G. Takaoka return; 127912a4e08a6440c95f29dc04efe83515a4ed045487Tadashi G. Takaoka } 1280979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1281923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1282f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard if (mHasUncommittedTypedChars) { 1283f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (mComposing.length() == 0 && switcher.isAlphabetMode() 1284f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka && switcher.isShiftedOrShiftLocked()) { 12850b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa mWord.setFirstCharCapitalized(true); 1286923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1287e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mComposing.append((char) code); 12888fbd55229243cb66c03d5ea1f79dfb39f596590dsatok mWord.add(code, keyCodes, x, y); 1289923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 1290923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 12911c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani // If it's the first letter, make note of auto-caps state 12921c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani if (mWord.size() == 1) { 1293b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mWord.setAutoCapitalized(getCurrentAutoCapsState()); 12941c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani } 1295923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.setComposingText(mComposing, 1); 1296923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1297d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 1298923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1299e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka sendKeyChar((char)code); 1300923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1301863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard if (mJustAddedMagicSpace && isMagicSpaceSwapper(primaryCode)) { 1302863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard swapSwapperAndSpace(); 1303863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard } else { 1304863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard mJustAddedMagicSpace = false; 1305863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard } 1306863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard 1307b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.updateShiftState(); 1308979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (LatinIME.PERF_DEBUG) measureCps(); 1309b5d17e52fcda39d540822e615bfb7ed5074e0034satok TextEntryState.typedCharacter((char) code, isWordSeparator(code), x, y); 1310923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1311923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1312b5d17e52fcda39d540822e615bfb7ed5074e0034satok private void handleSeparator(int primaryCode, int x, int y) { 1313b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.handleSeparator(); 13144f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 131555b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa // Should dismiss the "Touch again to save" message when handling separator 13166558253160e2039c87f424bd814f402ecd31de3bKen Wakasa if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) { 1317cb3320179d39a7983874697a0aa428b127675c9dJean Chalard mHandler.cancelUpdateBigramPredictions(); 1318d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 13196558253160e2039c87f424bd814f402ecd31de3bKen Wakasa } 13206558253160e2039c87f424bd814f402ecd31de3bKen Wakasa 1321923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project boolean pickedDefault = false; 1322923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Handle separator 13231b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final InputConnection ic = getCurrentInputConnection(); 1324923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 1325923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.beginBatchEdit(); 13269fbfd5877305ed19a20663630b498b6b3fdae942satok mRecorrection.abortRecorrection(false); 1327923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1328f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard if (mHasUncommittedTypedChars) { 1329923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // In certain languages where single quote is a separator, it's better 1330a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker // not to auto correct, but accept the typed word. For instance, 1331923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // in Italian dov' should not be expanded to dove' because the elision 1332923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // requires the last vowel to be removed. 13330730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard if (mAutoCorrectOn && primaryCode != Keyboard.CODE_SINGLE_QUOTE) { 1334b5d17e52fcda39d540822e615bfb7ed5074e0034satok pickedDefault = pickDefaultSuggestion(primaryCode); 1335923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1336923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project commitTyped(ic); 1337923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1338923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 13394ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa 1340863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard if (mJustAddedMagicSpace) { 1341863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard if (isMagicSpaceSwapper(primaryCode)) { 1342863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard sendKeyChar((char)primaryCode); 1343863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard swapSwapperAndSpace(); 1344863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard } else { 1345863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard if (isMagicSpaceStripper(primaryCode)) removeTrailingSpace(); 1346863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard sendKeyChar((char)primaryCode); 1347863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard mJustAddedMagicSpace = false; 1348863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard } 13490730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard } else { 13500730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard sendKeyChar((char)primaryCode); 13514ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa } 13524ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa 1353863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) { 1354863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard maybeDoubleSpace(); 1355863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard } 1356863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard 1357b5d17e52fcda39d540822e615bfb7ed5074e0034satok TextEntryState.typedCharacter((char) primaryCode, true, x, y); 135889bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard 1359979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (pickedDefault) { 136055b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka CharSequence typedWord = mWord.getTypedWord(); 136155b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka TextEntryState.backToAcceptedDefault(typedWord); 136255b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka if (!TextUtils.isEmpty(typedWord) && !typedWord.equals(mBestWord)) { 1363b2707856aba4fc9b063f26305f1fb603b19c1701satok InputConnectionCompatUtils.commitCorrection( 136489bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard ic, mLastSelectionEnd - typedWord.length(), typedWord, mBestWord); 136555b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka if (mCandidateView != null) 136655b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka mCandidateView.onAutoCorrectionInverted(mBestWord); 136755b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka } 136889bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 136989bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (Keyboard.CODE_SPACE == primaryCode) { 137089bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (!isCursorTouchingWord()) { 137189bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard mHandler.cancelUpdateSuggestions(); 137289bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard mHandler.cancelUpdateOldSuggestions(); 1373cb3320179d39a7983874697a0aa428b127675c9dJean Chalard mHandler.postUpdateBigramPredictions(); 137489bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 137589bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } else { 137689bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // Set punctuation right away. onUpdateSelection will fire but tests whether it is 137789bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // already displayed or not, so it's okay. 137855b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka setPunctuationSuggestions(); 1379923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1380b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 1381923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 1382923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.endBatchEdit(); 1383923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1384923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1385466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1386923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void handleClose() { 1387923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project commitTyped(getCurrentInputConnection()); 1388b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.handleClose(); 1389923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project requestHideSelf(0); 13901679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); 13911679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka if (inputView != null) 13921679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka inputView.closing(); 1393923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1394923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 13957a8dac55278cedd838be325f56b4c52d973c61f5satok public boolean isSuggestionsRequested() { 1396c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka return mIsSettingsSuggestionStripOn 1397c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka && (mCorrectionMode > 0 || isShowingSuggestionsStrip()); 1398923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1399a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 14007a8dac55278cedd838be325f56b4c52d973c61f5satok public boolean isShowingPunctuationList() { 14017e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka return mSuggestPuncList == mCandidateView.getSuggestions(); 14027599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 14037599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 14047a8dac55278cedd838be325f56b4c52d973c61f5satok public boolean isShowingSuggestionsStrip() { 14057599cfea4a2d56f4779452ec8e8742f7b9629cc0satok return (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_VALUE) 14067599cfea4a2d56f4779452ec8e8742f7b9629cc0satok || (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_ONLY_PORTRAIT_VALUE 14077599cfea4a2d56f4779452ec8e8742f7b9629cc0satok && mOrientation == Configuration.ORIENTATION_PORTRAIT); 14087599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 14097599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 14109fbfd5877305ed19a20663630b498b6b3fdae942satok public boolean isCandidateStripVisible() { 1411b5e00d5841b946de8970875231456228ae0eb6b1Ken Wakasa if (mCandidateView == null) 1412b5e00d5841b946de8970875231456228ae0eb6b1Ken Wakasa return false; 1413952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa if (mCandidateView.isShowingAddToDictionaryHint() || TextEntryState.isRecorrecting()) 14149fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return true; 14159fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (!isShowingSuggestionsStrip()) 14169fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return false; 14179fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mApplicationSpecifiedCompletionOn) 14189fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return true; 14199fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return isSuggestionsRequested(); 1420923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1421923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1422409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void switchToKeyboardView() { 1423060efb6d82af1f896d90cb845c8ae07c726f85e1satok if (DEBUG) { 1424060efb6d82af1f896d90cb845c8ae07c726f85e1satok Log.d(TAG, "Switch to keyboard view."); 1425060efb6d82af1f896d90cb845c8ae07c726f85e1satok } 1426060efb6d82af1f896d90cb845c8ae07c726f85e1satok View v = mKeyboardSwitcher.getInputView(); 1427060efb6d82af1f896d90cb845c8ae07c726f85e1satok if (v != null) { 1428060efb6d82af1f896d90cb845c8ae07c726f85e1satok // Confirms that the keyboard view doesn't have parent view. 1429060efb6d82af1f896d90cb845c8ae07c726f85e1satok ViewParent p = v.getParent(); 1430060efb6d82af1f896d90cb845c8ae07c726f85e1satok if (p != null && p instanceof ViewGroup) { 1431060efb6d82af1f896d90cb845c8ae07c726f85e1satok ((ViewGroup) p).removeView(v); 14325a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka } 1433060efb6d82af1f896d90cb845c8ae07c726f85e1satok setInputView(v); 1434060efb6d82af1f896d90cb845c8ae07c726f85e1satok } 1435060efb6d82af1f896d90cb845c8ae07c726f85e1satok setCandidatesViewShown(isCandidateStripVisible()); 1436060efb6d82af1f896d90cb845c8ae07c726f85e1satok updateInputViewShown(); 1437060efb6d82af1f896d90cb845c8ae07c726f85e1satok mHandler.postUpdateSuggestions(); 1438466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1439466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1440409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void clearSuggestions() { 14417e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka setSuggestions(SuggestedWords.EMPTY); 1442466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1443466741d8a78965b8509bf527344f289e50873092Mike LeBeau 14447e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka public void setSuggestions(SuggestedWords words) { 1445b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok if (mVoiceProxy.getAndResetIsShowingHint()) { 1446466741d8a78965b8509bf527344f289e50873092Mike LeBeau setCandidatesView(mCandidateViewContainer); 1447466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1448466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1449466741d8a78965b8509bf527344f289e50873092Mike LeBeau if (mCandidateView != null) { 14507e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka mCandidateView.setSuggestions(words); 14519ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka if (mCandidateView.isConfigCandidateHighlightFontColorEnabled()) { 14529ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka mKeyboardSwitcher.onAutoCorrectionStateChanged( 14539ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka words.hasWordAboveAutoCorrectionScoreThreshold()); 14549ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka } 1455466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1456466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1457466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1458409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void updateSuggestions() { 1459923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Check if we have a suggestion engine attached. 14609fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if ((mSuggest == null || !isSuggestionsRequested()) 1461b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok && !mVoiceProxy.isVoiceInputHighlighted()) { 1462923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1463923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1464466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1465f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard if (!mHasUncommittedTypedChars) { 1466ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setPunctuationSuggestions(); 1467923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1468923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1469979f8690967ff5409fe18f5085858ccdb8e0ccf1satok showSuggestions(mWord); 1470979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1471979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1472979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void showSuggestions(WordComposer word) { 14739f67e12a0e3f77985fb8bafe0db4c00e32317b9asatok // TODO: May need a better way of retrieving previous word 1474e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(), 1475979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mWordSeparators); 14767e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder( 14779ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka mKeyboardSwitcher.getInputView(), word, prevWord); 1478923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 14796f99d12b0752ecdbceda7e5fddead214f939f533Tadashi G. Takaoka boolean correctionAvailable = !mInputTypeNoAutoCorrect && mSuggest.hasAutoCorrection(); 1480a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa final CharSequence typedWord = word.getTypedWord(); 1481bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok // Here, we want to promote a whitelisted word if exists. 1482bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok final boolean typedWordValid = AutoCorrection.isValidWordForAutoCorrection( 1483bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok mSuggest.getUnigramDictionaries(), typedWord, preferCapitalization()); 1484979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mCorrectionMode == Suggest.CORRECTION_FULL 1485979f8690967ff5409fe18f5085858ccdb8e0ccf1satok || mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM) { 1486923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project correctionAvailable |= typedWordValid; 1487923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 14884a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani // Don't auto-correct words with multiple capital letter 1489979f8690967ff5409fe18f5085858ccdb8e0ccf1satok correctionAvailable &= !word.isMostlyCaps(); 1490952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa correctionAvailable &= !TextEntryState.isRecorrecting(); 1491979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1492a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa // Basically, we update the suggestion strip only when suggestion count > 1. However, 1493a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa // there is an exception: We update the suggestion strip whenever typed word's length 1494f3df63a93a8f623e2aca5895ee749bd297b58d12Tadashi G. Takaoka // is 1 or typed word is found in dictionary, regardless of suggestion count. Actually, 1495f3df63a93a8f623e2aca5895ee749bd297b58d12Tadashi G. Takaoka // in most cases, suggestion count is 1 when typed word's length is 1, but we do always 1496f3df63a93a8f623e2aca5895ee749bd297b58d12Tadashi G. Takaoka // need to clear the previous state when the user starts typing a word (i.e. typed word's 1497f3df63a93a8f623e2aca5895ee749bd297b58d12Tadashi G. Takaoka // length == 1). 1498f3df63a93a8f623e2aca5895ee749bd297b58d12Tadashi G. Takaoka if (builder.size() > 1 || typedWord.length() == 1 || typedWordValid 1499a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa || mCandidateView.isShowingAddToDictionaryHint()) { 15009fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka builder.setTypedWordValid(typedWordValid).setHasMinimalSuggestion(correctionAvailable); 15019fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka } else { 15029fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka final SuggestedWords previousSuggestions = mCandidateView.getSuggestions(); 15039fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (previousSuggestions == mSuggestPuncList) 15049fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return; 15059fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka builder.addTypedWordAndPreviousSuggestions(typedWord, previousSuggestions); 15069fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka } 15077e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka showSuggestions(builder.build(), typedWord); 1508979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 15094a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani 15109fbfd5877305ed19a20663630b498b6b3fdae942satok public void showSuggestions(SuggestedWords suggestedWords, CharSequence typedWord) { 15117e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka setSuggestions(suggestedWords); 15127e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka if (suggestedWords.size() > 0) { 151314e427d5bb13d59d23fb317ef90a6c44ae279425satok if (Utils.shouldBlockedBySafetyNetForAutoCorrection(suggestedWords, mSuggest)) { 151482411d47ba7e8133ed2390c6920945e139a738cesatok mBestWord = typedWord; 151582411d47ba7e8133ed2390c6920945e139a738cesatok } else if (suggestedWords.hasAutoCorrectionWord()) { 15167e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka mBestWord = suggestedWords.getWord(1); 1517923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1518923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mBestWord = typedWord; 1519923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1520923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1521923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mBestWord = null; 1522923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1523ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setCandidatesViewShown(isCandidateStripVisible()); 1524923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1525923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1526b5d17e52fcda39d540822e615bfb7ed5074e0034satok private boolean pickDefaultSuggestion(int separatorCode) { 1527923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Complete any pending candidate query first 1528d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka if (mHandler.hasPendingUpdateSuggestions()) { 1529d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.cancelUpdateSuggestions(); 1530923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project updateSuggestions(); 1531923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 15326780b898ec2647a21319601a03ae1c393c0e1b29Amith Yamasani if (mBestWord != null && mBestWord.length() > 0) { 1533b5d17e52fcda39d540822e615bfb7ed5074e0034satok TextEntryState.acceptedDefault(mWord.getTypedWord(), mBestWord, separatorCode); 1534923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mJustAccepted = true; 153555b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka pickSuggestion(mBestWord); 15369468335a06d2b0e3ef15f4f57f8c1b0857b34ebeAmith Yamasani // Add the word to the auto dictionary if it's not a known word 1537bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok addToAutoAndUserBigramDictionaries(mBestWord, AutoDictionary.FREQUENCY_FOR_TYPED); 1538979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return true; 1539979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1540923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1541979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return false; 1542923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1543923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1544923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void pickSuggestionManually(int index, CharSequence suggestion) { 15457e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords suggestions = mCandidateView.getSuggestions(); 1546b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.flushAndLogAllTextModificationCounters(index, suggestion, mWordSeparators); 15474f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1548952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa final boolean recorrecting = TextEntryState.isRecorrecting(); 15499a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa InputConnection ic = getCurrentInputConnection(); 15509a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic != null) { 15519a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.beginBatchEdit(); 15529a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 15531b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka if (mApplicationSpecifiedCompletionOn && mApplicationSpecifiedCompletions != null 15541b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka && index >= 0 && index < mApplicationSpecifiedCompletions.length) { 15551b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka CompletionInfo ci = mApplicationSpecifiedCompletions[index]; 1556923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 1557923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.commitCompletion(ci); 1558923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1559923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCommittedLength = suggestion.length(); 1560923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mCandidateView != null) { 1561923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCandidateView.clear(); 1562923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1563b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 15649a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic != null) { 15659a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.endBatchEdit(); 15669a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 1567923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1568923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 15696a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani 15706a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani // If this is a punctuation, apply it through the normal key press 1571979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (suggestion.length() == 1 && (isWordSeparator(suggestion.charAt(0)) 1572979f8690967ff5409fe18f5085858ccdb8e0ccf1satok || isSuggestedPunctuation(suggestion.charAt(0)))) { 1573979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Word separators are suggested before the user inputs something. 1574979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // So, LatinImeLogger logs "" as a user's input. 1575979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.logOnManualSuggestion( 15767e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka "", suggestion.toString(), index, suggestions.mWords); 1577863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard // Find out whether the previous character is a space. If it is, as a special case 1578863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard // for punctuation entered through the suggestion strip, it should be considered 1579863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard // a magic space even if it was a normal space. This is meant to help in case the user 1580863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard // pressed space on purpose of displaying the suggestion strip punctuation. 158155b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa final char primaryCode = suggestion.charAt(0); 1582863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard final int toLeft = (ic == null) ? 0 : ic.getTextBeforeCursor(1, 0).charAt(0); 15834f3b59711f6985d39e0cc908d2431ae6715d9b26Jean Chalard final boolean oldMagicSpace = mJustAddedMagicSpace; 1584863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard if (Keyboard.CODE_SPACE == toLeft) mJustAddedMagicSpace = true; 1585a96574fdd5e38a237a35b21a2b7c20a29138c648Tadashi G. Takaoka onCodeInput(primaryCode, new int[] { primaryCode }, 1586a96574fdd5e38a237a35b21a2b7c20a29138c648Tadashi G. Takaoka KeyboardActionListener.NOT_A_TOUCH_COORDINATE, 1587a96574fdd5e38a237a35b21a2b7c20a29138c648Tadashi G. Takaoka KeyboardActionListener.NOT_A_TOUCH_COORDINATE); 15884f3b59711f6985d39e0cc908d2431ae6715d9b26Jean Chalard mJustAddedMagicSpace = oldMagicSpace; 15899a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic != null) { 15909a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.endBatchEdit(); 15919a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 15926a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani return; 15936a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 1594f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard if (!mHasUncommittedTypedChars) { 159589bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // If we are not composing a word, then it was a suggestion inferred from 159689bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // context - no user input. We should reset the word composer. 159789bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard mWord.reset(); 159889bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 15999a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAccepted = true; 160055b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka pickSuggestion(suggestion); 16019468335a06d2b0e3ef15f4f57f8c1b0857b34ebeAmith Yamasani // Add the word to the auto dictionary if it's not a known word 16020c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani if (index == 0) { 1603bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok addToAutoAndUserBigramDictionaries(suggestion, AutoDictionary.FREQUENCY_FOR_PICKED); 1604979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } else { 1605bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok addToOnlyBigramDictionary(suggestion, 1); 16060c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani } 1607979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.logOnManualSuggestion(mComposing.toString(), suggestion.toString(), 16087e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka index, suggestions.mWords); 1609923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.acceptedSuggestion(mComposing.toString(), suggestion); 1610923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Follow it with a space 16110730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard if (mShouldInsertMagicSpace && !recorrecting) { 16120730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard sendMagicSpace(); 1613923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1614979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 16157f2ba16aa2adba95e0575a2c6d58f6240154f313Jean Chalard // We should show the hint if the user pressed the first entry AND either: 16167f2ba16aa2adba95e0575a2c6d58f6240154f313Jean Chalard // - There is no dictionary (we know that because we tried to load it => null != mSuggest 16177f2ba16aa2adba95e0575a2c6d58f6240154f313Jean Chalard // AND mHasDictionary is false) 16187f2ba16aa2adba95e0575a2c6d58f6240154f313Jean Chalard // - There is a dictionary and the word is not in it 16197f2ba16aa2adba95e0575a2c6d58f6240154f313Jean Chalard // Please note that if mSuggest is null, it means that everything is off: suggestion 16207f2ba16aa2adba95e0575a2c6d58f6240154f313Jean Chalard // and correction, so we shouldn't try to show the hint 16217f2ba16aa2adba95e0575a2c6d58f6240154f313Jean Chalard // We used to look at mCorrectionMode here, but showing the hint should have nothing 16227f2ba16aa2adba95e0575a2c6d58f6240154f313Jean Chalard // to do with the autocorrection setting. 1623bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok final boolean showingAddToDictionaryHint = index == 0 && mSuggest != null 1624bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok // If there is no dictionary the hint should be shown. 1625bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok && (!mHasDictionary 1626bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok // If "suggestion" is not in the dictionary, the hint should be shown. 1627bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok || !AutoCorrection.isValidWord( 1628bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok mSuggest.getUnigramDictionaries(), suggestion, true)); 1629b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani 1630952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa if (!recorrecting) { 1631b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // Fool the state watcher so that a subsequent backspace will not do a revert, unless 1632b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // we just did a correction, in which case we need to stay in 1633b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // TextEntryState.State.PICKED_SUGGESTION state. 1634b5d17e52fcda39d540822e615bfb7ed5074e0034satok TextEntryState.typedCharacter((char) Keyboard.CODE_SPACE, true, 1635b5d17e52fcda39d540822e615bfb7ed5074e0034satok WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE); 163689bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // From there on onUpdateSelection() will fire so suggestions will be updated 1637b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } else if (!showingAddToDictionaryHint) { 1638364da8c618303a7764595d2c15ee034a7671365dKen Wakasa // If we're not showing the "Touch again to save", then show corrections again. 1639979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // In case the cursor position doesn't change, make sure we show the suggestions again. 1640b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani clearSuggestions(); 1641d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateOldSuggestions(); 1642979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1643b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (showingAddToDictionaryHint) { 164466a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani mCandidateView.showAddToDictionaryHint(suggestion); 164566a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani } 16469a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic != null) { 16479a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.endBatchEdit(); 16489a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 1649923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1650a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1651979f8690967ff5409fe18f5085858ccdb8e0ccf1satok /** 1652979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * Commits the chosen word to the text field and saves it for later 1653979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * retrieval. 1654979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * @param suggestion the suggestion picked by the user to be committed to 1655979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * the text field 1656979f8690967ff5409fe18f5085858ccdb8e0ccf1satok */ 165755b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka private void pickSuggestion(CharSequence suggestion) { 1658b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 1659b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (!switcher.isKeyboardAvailable()) 16601679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka return; 1661923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 1662923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 1663b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.rememberReplacedWord(suggestion, mWordSeparators); 1664979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ic.commitText(suggestion, 1); 1665923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1666f733074aaecdfd6e89cfee2daff8a9c1233b60f1satok mRecorrection.saveRecorrectionSuggestion(mWord, suggestion); 1667f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard mHasUncommittedTypedChars = false; 1668923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCommittedLength = suggestion.length(); 1669923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1670923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 167189bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard private static final WordComposer sEmptyWordComposer = new WordComposer(); 1672cb3320179d39a7983874697a0aa428b127675c9dJean Chalard private void updateBigramPredictions() { 167389bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (mSuggest == null || !isSuggestionsRequested()) 167489bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard return; 167589bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard 1676cb3320179d39a7983874697a0aa428b127675c9dJean Chalard if (!mBigramPredictionEnabled) { 1677cb3320179d39a7983874697a0aa428b127675c9dJean Chalard setPunctuationSuggestions(); 1678cb3320179d39a7983874697a0aa428b127675c9dJean Chalard return; 1679cb3320179d39a7983874697a0aa428b127675c9dJean Chalard } 1680cb3320179d39a7983874697a0aa428b127675c9dJean Chalard 168189bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard final CharSequence prevWord = EditingUtils.getThisWord(getCurrentInputConnection(), 168289bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard mWordSeparators); 168389bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder( 168489bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard mKeyboardSwitcher.getInputView(), sEmptyWordComposer, prevWord); 168589bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard 168689bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (builder.size() > 0) { 168789bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // Explicitly supply an empty typed word (the no-second-arg version of 168889bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // showSuggestions will retrieve the word near the cursor, we don't want that here) 168989bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard showSuggestions(builder.build(), ""); 169089bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } else { 169189bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (!isShowingPunctuationList()) setPunctuationSuggestions(); 169289bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 169389bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 169489bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard 16957a8dac55278cedd838be325f56b4c52d973c61f5satok public void setPunctuationSuggestions() { 16967e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka setSuggestions(mSuggestPuncList); 16979fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka setCandidatesViewShown(isCandidateStripVisible()); 16986a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 16996a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani 1700bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok private void addToAutoAndUserBigramDictionaries(CharSequence suggestion, int frequencyDelta) { 1701979f8690967ff5409fe18f5085858ccdb8e0ccf1satok checkAddToDictionary(suggestion, frequencyDelta, false); 1702979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1703979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1704bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok private void addToOnlyBigramDictionary(CharSequence suggestion, int frequencyDelta) { 1705979f8690967ff5409fe18f5085858ccdb8e0ccf1satok checkAddToDictionary(suggestion, frequencyDelta, true); 1706979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1707979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1708979f8690967ff5409fe18f5085858ccdb8e0ccf1satok /** 1709979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * Adds to the UserBigramDictionary and/or AutoDictionary 1710bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok * @param selectedANotTypedWord true if it should be added to bigram dictionary if possible 1711979f8690967ff5409fe18f5085858ccdb8e0ccf1satok */ 1712979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void checkAddToDictionary(CharSequence suggestion, int frequencyDelta, 1713bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok boolean selectedANotTypedWord) { 1714979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (suggestion == null || suggestion.length() < 1) return; 1715bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok 17160c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani // Only auto-add to dictionary if auto-correct is ON. Otherwise we'll be 17170c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani // adding words in situations where the user or application really didn't 17180c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani // want corrections enabled or learned. 1719979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (!(mCorrectionMode == Suggest.CORRECTION_FULL 1720979f8690967ff5409fe18f5085858ccdb8e0ccf1satok || mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM)) { 1721979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return; 1722979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1723bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok 1724bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok final boolean selectedATypedWordAndItsInAutoDic = 1725bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok !selectedANotTypedWord && mAutoDictionary.isValidWord(suggestion); 1726bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok final boolean isValidWord = AutoCorrection.isValidWord( 1727bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok mSuggest.getUnigramDictionaries(), suggestion, true); 1728bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok final boolean needsToAddToAutoDictionary = selectedATypedWordAndItsInAutoDic 1729bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok || !isValidWord; 1730bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok if (needsToAddToAutoDictionary) { 1731e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mAutoDictionary.addWord(suggestion.toString(), frequencyDelta); 1732e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } 1733979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1734e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (mUserBigramDictionary != null) { 1735863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard // We don't want to register as bigrams words separated by a separator. 1736863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard // For example "I will, and you too" : we don't want the pair ("will" "and") to be 1737863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard // a bigram. 1738e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(), 1739863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard mWordSeparators); 1740e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (!TextUtils.isEmpty(prevWord)) { 1741e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mUserBigramDictionary.addBigrams(prevWord.toString(), suggestion.toString()); 1742979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 174332e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani } 174432e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani } 174532e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani 17467a8dac55278cedd838be325f56b4c52d973c61f5satok public boolean isCursorTouchingWord() { 1747923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 1748923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic == null) return false; 1749923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence toLeft = ic.getTextBeforeCursor(1, 0); 1750923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence toRight = ic.getTextAfterCursor(1, 0); 1751923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (!TextUtils.isEmpty(toLeft) 175255b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa && !isWordSeparator(toLeft.charAt(0)) 175355b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa && !isSuggestedPunctuation(toLeft.charAt(0))) { 1754923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 1755923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1756a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker if (!TextUtils.isEmpty(toRight) 175755b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa && !isWordSeparator(toRight.charAt(0)) 175855b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa && !isSuggestedPunctuation(toRight.charAt(0))) { 1759923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 1760923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1761923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return false; 1762923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1763a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1764dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani private boolean sameAsTextBeforeCursor(InputConnection ic, CharSequence text) { 1765dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani CharSequence beforeText = ic.getTextBeforeCursor(text.length(), 0); 1766dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani return TextUtils.equals(text, beforeText); 1767dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani } 1768dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani 1769923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void revertLastWord(boolean deleteChar) { 1770923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int length = mComposing.length(); 1771f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard if (!mHasUncommittedTypedChars && length > 0) { 1772923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final InputConnection ic = getCurrentInputConnection(); 1773504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka final CharSequence punctuation = ic.getTextBeforeCursor(1, 0); 1774923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (deleteChar) ic.deleteSurroundingText(1, 0); 1775923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int toDelete = mCommittedLength; 1776504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka final CharSequence toTheLeft = ic.getTextBeforeCursor(mCommittedLength, 0); 1777504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka if (!TextUtils.isEmpty(toTheLeft) && isWordSeparator(toTheLeft.charAt(0))) { 1778923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project toDelete--; 1779923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1780923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.deleteSurroundingText(toDelete, 0); 178130be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka // Re-insert punctuation only when the deleted character was word separator and the 178230be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka // composing text wasn't equal to the auto-corrected text. 178330be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka if (deleteChar 178430be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka && !TextUtils.isEmpty(punctuation) && isWordSeparator(punctuation.charAt(0)) 178530be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka && !TextUtils.equals(mComposing, toTheLeft)) { 1786504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka ic.commitText(mComposing, 1); 1787504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka TextEntryState.acceptedTyped(mComposing); 178830be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka ic.commitText(punctuation, 1); 1789b5d17e52fcda39d540822e615bfb7ed5074e0034satok TextEntryState.typedCharacter(punctuation.charAt(0), true, 1790b5d17e52fcda39d540822e615bfb7ed5074e0034satok WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE); 179130be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka // Clear composing text 179230be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka mComposing.setLength(0); 1793504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka } else { 1794f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard mHasUncommittedTypedChars = true; 1795504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka ic.setComposingText(mComposing, 1); 1796504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka TextEntryState.backspace(); 1797504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka } 1798cb3320179d39a7983874697a0aa428b127675c9dJean Chalard mHandler.cancelUpdateBigramPredictions(); 1799d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 1800923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1801923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); 1802923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1803923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1804923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1805923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project protected String getWordSeparators() { 1806923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return mWordSeparators; 1807923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1808a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1809923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean isWordSeparator(int code) { 1810923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project String separators = getWordSeparators(); 1811923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return separators.contains(String.valueOf((char)code)); 1812923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1813923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1814863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard private boolean isMagicSpaceStripper(int code) { 1815863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard return mMagicSpaceStrippers.contains(String.valueOf((char)code)); 1816863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard } 1817863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard 1818863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard private boolean isMagicSpaceSwapper(int code) { 1819863f95b6052e5d9d4fb1ac5dc283c464db9f29c3Jean Chalard return mMagicSpaceSwappers.contains(String.valueOf((char)code)); 1820923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1821923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 18220730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard private void sendMagicSpace() { 1823571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka sendKeyChar((char)Keyboard.CODE_SPACE); 18240730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard mJustAddedMagicSpace = true; 1825b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 1826923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1827923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1828923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean preferCapitalization() { 18290b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa return mWord.isFirstCharCapitalized(); 1830923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1831923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 183288fc9d44186120f9edc5cf7ec0e2af85260fed04satok // Notify that language or mode have been changed and toggleLanguage will update KeyboardID 1833c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // according to new language or mode. 1834c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka public void onRefreshKeyboard() { 18354ab730dbd34fad323063f2ffd31ce33de746668dsatok // Reload keyboard because the current language has been changed. 1836cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), 1837b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mSubtypeSwitcher.isShortcutImeEnabled() && mVoiceProxy.isVoiceButtonEnabled(), 1838b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.isVoiceButtonOnPrimary()); 18390ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok initSuggest(); 18404b13b4f94215368c6387b2564bdaf2cbcbe4c130Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 184136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 184236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 184388fc9d44186120f9edc5cf7ec0e2af85260fed04satok // "reset" and "next" are used only for USE_SPACEBAR_LANGUAGE_SWITCHER. 184488fc9d44186120f9edc5cf7ec0e2af85260fed04satok private void toggleLanguage(boolean next) { 184588fc9d44186120f9edc5cf7ec0e2af85260fed04satok if (mSubtypeSwitcher.useSpacebarLanguageSwitcher()) { 184688fc9d44186120f9edc5cf7ec0e2af85260fed04satok mSubtypeSwitcher.toggleLanguage(next); 184788fc9d44186120f9edc5cf7ec0e2af85260fed04satok } 184888fc9d44186120f9edc5cf7ec0e2af85260fed04satok onRefreshKeyboard();// no need?? 184988fc9d44186120f9edc5cf7ec0e2af85260fed04satok } 185088fc9d44186120f9edc5cf7ec0e2af85260fed04satok 18515a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 18528aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka public void onSwipeDown() { 1853363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka if (mConfigSwipeDownDismissKeyboardEnabled) 1854363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka handleClose(); 1855923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1856923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 18575a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 1858e59491460b0411bed430a5ca6eca0c56c5bf18d9Tadashi G. Takaoka public void onPress(int primaryCode, boolean withSliding) { 1859cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka if (mKeyboardSwitcher.isVibrateAndSoundFeedbackRequired()) { 1860cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka vibrate(); 1861cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka playKeyClick(primaryCode); 1862cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka } 18631679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 18641679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); 1865571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) { 1866e59491460b0411bed430a5ca6eca0c56c5bf18d9Tadashi G. Takaoka switcher.onPressShift(withSliding); 1867e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka } else if (distinctMultiTouch && primaryCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) { 18686c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka switcher.onPressSymbol(); 186940a05f62edc6cdedb4365a722b48a72826ef2bf6Tadashi G. Takaoka } else { 18706c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka switcher.onOtherKeyPressed(); 1871681b102a492b7d5301c1ca87985b4c391eb5eb14Tadashi G. Takaoka } 1872dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette mAccessibilityUtils.onPress(primaryCode, switcher); 1873923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1874923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 18755a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 1876e59491460b0411bed430a5ca6eca0c56c5bf18d9Tadashi G. Takaoka public void onRelease(int primaryCode, boolean withSliding) { 18771679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 18783f7d75060afb2bb7e74879bcbbdcb9700ec5c2d6Amith Yamasani // Reset any drag flags in the keyboard 18791679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); 1880571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) { 1881e59491460b0411bed430a5ca6eca0c56c5bf18d9Tadashi G. Takaoka switcher.onReleaseShift(withSliding); 1882e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka } else if (distinctMultiTouch && primaryCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) { 18836c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka switcher.onReleaseSymbol(); 188440a05f62edc6cdedb4365a722b48a72826ef2bf6Tadashi G. Takaoka } 1885dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette mAccessibilityUtils.onRelease(primaryCode, switcher); 1886923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1887a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1888a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1889123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka // receive ringer mode change and network state change. 1890923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private BroadcastReceiver mReceiver = new BroadcastReceiver() { 1891923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 1892923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onReceive(Context context, Intent intent) { 1893123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka final String action = intent.getAction(); 1894123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) { 1895123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka updateRingerMode(); 1896123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 1897123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka mSubtypeSwitcher.onNetworkStateChanged(intent); 1898123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka } 1899923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1900923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project }; 1901923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1902923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // update flags for silent mode 1903923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void updateRingerMode() { 1904923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mAudioManager == null) { 1905923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 1906923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1907923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mAudioManager != null) { 1908923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSilentMode = (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL); 1909923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1910923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1911923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1912923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void playKeyClick(int primaryCode) { 1913923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // if mAudioManager is null, we don't have the ringer state yet 1914923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // mAudioManager will be set by updateRingerMode 1915923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mAudioManager == null) { 1916979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mKeyboardSwitcher.getInputView() != null) { 1917923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project updateRingerMode(); 1918923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1919923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1920923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mSoundOn && !mSilentMode) { 1921923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // FIXME: Volume and enable should come from UI settings 1922923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // FIXME: These should be triggered after auto-repeat logic 1923923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int sound = AudioManager.FX_KEYPRESS_STANDARD; 1924923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (primaryCode) { 1925571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_DELETE: 1926923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sound = AudioManager.FX_KEYPRESS_DELETE; 1927923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 1928571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_ENTER: 1929923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sound = AudioManager.FX_KEYPRESS_RETURN; 1930923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 1931571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_SPACE: 1932923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sound = AudioManager.FX_KEYPRESS_SPACEBAR; 1933923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 1934923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1935923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mAudioManager.playSoundEffect(sound, FX_VOLUME); 1936923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1937923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1938923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1939409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void vibrate() { 1940923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (!mVibrateOn) { 1941923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1942923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 19431679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); 19441679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka if (inputView != null) { 19451679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka inputView.performHapticFeedback( 1946979f8690967ff5409fe18f5085858ccdb8e0ccf1satok HapticFeedbackConstants.KEYBOARD_TAP, 194766a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); 1948923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1949923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1950923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 195171c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka public void promoteToUserDictionary(String word, int frequency) { 195234386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani if (mUserDictionary.isValidWord(word)) return; 195334386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani mUserDictionary.addWord(word, frequency); 195434386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani } 195534386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani 195671c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka public WordComposer getCurrentWord() { 19576516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani return mWord; 19586516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani } 19596516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani 196071c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka public boolean getPopupOn() { 1961979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return mPopupOn; 1962979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1963979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1964e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani private void updateCorrectionMode() { 19659f67e12a0e3f77985fb8bafe0db4c00e32317b9asatok // TODO: cleanup messy flags 1966e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mHasDictionary = mSuggest != null ? mSuggest.hasMainDictionary() : false; 1967e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mAutoCorrectOn = (mAutoCorrectEnabled || mQuickFixes) 1968e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani && !mInputTypeNoAutoCorrect && mHasDictionary; 196932e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani mCorrectionMode = (mAutoCorrectOn && mAutoCorrectEnabled) 1970e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani ? Suggest.CORRECTION_FULL 197132e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani : (mAutoCorrectOn ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE); 1972979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mCorrectionMode = (mBigramSuggestionEnabled && mAutoCorrectOn && mAutoCorrectEnabled) 1973979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ? Suggest.CORRECTION_FULL_BIGRAM : mCorrectionMode; 1974e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani if (mSuggest != null) { 1975e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mSuggest.setCorrectionMode(mCorrectionMode); 1976e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani } 1977e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani } 1978e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani 19790ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private void updateAutoTextEnabled() { 198032e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani if (mSuggest == null) return; 19815ef096f5f601c759e8a4a888aaca91ac5ccd9974Tadashi G. Takaoka mSuggest.setQuickFixesEnabled(mQuickFixes 19824ab730dbd34fad323063f2ffd31ce33de746668dsatok && SubtypeSwitcher.getInstance().isSystemLanguageSameAsInputLanguage()); 198332e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani } 198432e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani 19857599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private void updateSuggestionVisibility(SharedPreferences prefs) { 1986458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa final Resources res = mResources; 19877599cfea4a2d56f4779452ec8e8742f7b9629cc0satok final String suggestionVisiblityStr = prefs.getString( 19889502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka Settings.PREF_SHOW_SUGGESTIONS_SETTING, 1989458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa res.getString(R.string.prefs_suggestion_visibility_default_value)); 19907599cfea4a2d56f4779452ec8e8742f7b9629cc0satok for (int visibility : SUGGESTION_VISIBILITY_VALUE_ARRAY) { 1991458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa if (suggestionVisiblityStr.equals(res.getString(visibility))) { 19927599cfea4a2d56f4779452ec8e8742f7b9629cc0satok mSuggestionVisibility = visibility; 19937599cfea4a2d56f4779452ec8e8742f7b9629cc0satok break; 19947599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 19957599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 19967599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 19977599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 1998466741d8a78965b8509bf527344f289e50873092Mike LeBeau protected void launchSettings() { 19999502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka launchSettings(Settings.class); 2000466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 2001466741d8a78965b8509bf527344f289e50873092Mike LeBeau 2002bf96661d33d0126adb60a48880ceba1ff055d4a4satok public void launchDebugSettings() { 20039502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka launchSettings(DebugSettings.class); 2004bf96661d33d0126adb60a48880ceba1ff055d4a4satok } 2005bf96661d33d0126adb60a48880ceba1ff055d4a4satok 2006507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka protected void launchSettings(Class<? extends PreferenceActivity> settingsClass) { 2007923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project handleClose(); 2008923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project Intent intent = new Intent(); 2009466741d8a78965b8509bf527344f289e50873092Mike LeBeau intent.setClass(LatinIME.this, settingsClass); 2010923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2011923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project startActivity(intent); 2012923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2013923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2014507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka private void loadSettings(EditorInfo attribute) { 2015923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Get the settings preferences 201627d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa final SharedPreferences prefs = mPrefs; 2017699e429f1913197650cc2fc2d8cb6e506be66842satok final boolean hasVibrator = VibratorCompatWrapper.getInstance(this).hasVibrator(); 2018699e429f1913197650cc2fc2d8cb6e506be66842satok mVibrateOn = hasVibrator && prefs.getBoolean(Settings.PREF_VIBRATE_ON, false); 2019f0d99b8677afdde39c16d414d44bfafcaea94b50Jean Chalard mSoundOn = prefs.getBoolean(Settings.PREF_SOUND_ON, 2020f0d99b8677afdde39c16d414d44bfafcaea94b50Jean Chalard mResources.getBoolean(R.bool.config_default_sound_enabled)); 2021728115493e14f84d5f02a4812c8086a378813364Jean Chalard 2022728115493e14f84d5f02a4812c8086a378813364Jean Chalard mPopupOn = isPopupEnabled(prefs); 20239502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true); 202489764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard mQuickFixes = isQuickFixesEnabled(prefs); 2025a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 202627d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa mAutoCorrectEnabled = isAutoCorrectEnabled(prefs); 202727d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa mBigramSuggestionEnabled = mAutoCorrectEnabled && isBigramSuggestionEnabled(prefs); 2028b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard mBigramPredictionEnabled = mBigramSuggestionEnabled && isBigramPredictionEnabled(prefs); 20291b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka loadAndSetAutoCorrectionThreshold(prefs); 2030466741d8a78965b8509bf527344f289e50873092Mike LeBeau 2031b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.loadSettings(attribute, prefs); 2032409220583333bdf06290dd9fd42f91b5c0d1b11asatok 2033e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani updateCorrectionMode(); 20340ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok updateAutoTextEnabled(); 203527d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa updateSuggestionVisibility(prefs); 203688fc9d44186120f9edc5cf7ec0e2af85260fed04satok 203788fc9d44186120f9edc5cf7ec0e2af85260fed04satok // This will work only when the subtype is not supported. 203888fc9d44186120f9edc5cf7ec0e2af85260fed04satok LanguageSwitcherProxy.loadSettings(); 203936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 204036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 2041b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda /** 20421b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka * Load Auto correction threshold from SharedPreferences, and modify mSuggest's threshold. 2043b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda */ 20441b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka private void loadAndSetAutoCorrectionThreshold(SharedPreferences sp) { 2045b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda // When mSuggest is not initialized, cannnot modify mSuggest's threshold. 2046b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda if (mSuggest == null) return; 20471b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // When auto correction setting is turned off, the threshold is ignored. 2048b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda if (!isAutoCorrectEnabled(sp)) return; 2049b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda 20501b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final String currentAutoCorrectionSetting = sp.getString( 20511b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka Settings.PREF_AUTO_CORRECTION_THRESHOLD, 20529ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka mResources.getString(R.string.auto_correction_threshold_mode_index_modest)); 20531b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final String[] autoCorrectionThresholdValues = mResources.getStringArray( 20549ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka R.array.auto_correction_threshold_values); 20551b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // When autoCrrectionThreshold is greater than 1.0, auto correction is virtually turned off. 20561b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka double autoCorrectionThreshold = Double.MAX_VALUE; 2057b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda try { 20581b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final int arrayIndex = Integer.valueOf(currentAutoCorrectionSetting); 20591b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka if (arrayIndex >= 0 && arrayIndex < autoCorrectionThresholdValues.length) { 20601b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka autoCorrectionThreshold = Double.parseDouble( 20611b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka autoCorrectionThresholdValues[arrayIndex]); 2062b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2063b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } catch (NumberFormatException e) { 20641b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // Whenever the threshold settings are correct, never come here. 20651b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka autoCorrectionThreshold = Double.MAX_VALUE; 20661b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka Log.w(TAG, "Cannot load auto correction threshold setting." 20671b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka + " currentAutoCorrectionSetting: " + currentAutoCorrectionSetting 20681b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka + ", autoCorrectionThresholdValues: " 20691b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka + Arrays.toString(autoCorrectionThresholdValues)); 2070b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2071b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda // TODO: This should be refactored : 20721b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // setAutoCorrectionThreshold should be called outside of this method. 20731b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mSuggest.setAutoCorrectionThreshold(autoCorrectionThreshold); 2074b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2075b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda 2076728115493e14f84d5f02a4812c8086a378813364Jean Chalard private boolean isPopupEnabled(SharedPreferences sp) { 2077728115493e14f84d5f02a4812c8086a378813364Jean Chalard final boolean showPopupOption = getResources().getBoolean( 2078728115493e14f84d5f02a4812c8086a378813364Jean Chalard R.bool.config_enable_show_popup_on_keypress_option); 2079728115493e14f84d5f02a4812c8086a378813364Jean Chalard if (!showPopupOption) return mResources.getBoolean(R.bool.config_default_popup_preview); 2080728115493e14f84d5f02a4812c8086a378813364Jean Chalard return sp.getBoolean(Settings.PREF_POPUP_ON, 2081728115493e14f84d5f02a4812c8086a378813364Jean Chalard mResources.getBoolean(R.bool.config_default_popup_preview)); 2082728115493e14f84d5f02a4812c8086a378813364Jean Chalard } 2083728115493e14f84d5f02a4812c8086a378813364Jean Chalard 208489764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard private boolean isQuickFixesEnabled(SharedPreferences sp) { 208589764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard final boolean showQuickFixesOption = mResources.getBoolean( 208689764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard R.bool.config_enable_quick_fixes_option); 208789764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard if (!showQuickFixesOption) { 208889764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard return isAutoCorrectEnabled(sp); 208989764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard } 209089764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard return sp.getBoolean(Settings.PREF_QUICK_FIXES, mResources.getBoolean( 209189764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard R.bool.config_default_quick_fixes)); 209289764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard } 209389764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard 2094b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda private boolean isAutoCorrectEnabled(SharedPreferences sp) { 20951b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final String currentAutoCorrectionSetting = sp.getString( 20961b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka Settings.PREF_AUTO_CORRECTION_THRESHOLD, 20979ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka mResources.getString(R.string.auto_correction_threshold_mode_index_modest)); 20981b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final String autoCorrectionOff = mResources.getString( 20999ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka R.string.auto_correction_threshold_mode_index_off); 21001b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka return !currentAutoCorrectionSetting.equals(autoCorrectionOff); 2101b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2102b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda 2103b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda private boolean isBigramSuggestionEnabled(SharedPreferences sp) { 210489764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard final boolean showBigramSuggestionsOption = mResources.getBoolean( 210589764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard R.bool.config_enable_bigram_suggestions_option); 210689764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard if (!showBigramSuggestionsOption) { 210789764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard return isAutoCorrectEnabled(sp); 210889764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard } 210989764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard return sp.getBoolean(Settings.PREF_BIGRAM_SUGGESTIONS, mResources.getBoolean( 211089764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard R.bool.config_default_bigram_suggestions)); 2111b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2112b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda 2113b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard private boolean isBigramPredictionEnabled(SharedPreferences sp) { 2114b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard return sp.getBoolean(Settings.PREF_BIGRAM_PREDICTIONS, mResources.getBoolean( 2115b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard R.bool.config_default_bigram_prediction)); 2116b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard } 2117b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard 21186a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani private void initSuggestPuncList() { 21197e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka if (mSuggestPuncs != null || mSuggestPuncList != null) 21207e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka return; 21217e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords.Builder builder = new SuggestedWords.Builder(); 21227e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka String puncs = mResources.getString(R.string.suggested_punctuations); 21237e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka if (puncs != null) { 21247e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka for (int i = 0; i < puncs.length(); i++) { 21257e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka builder.addWord(puncs.subSequence(i, i + 1)); 21266a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 21276a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 21287e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka mSuggestPuncList = builder.build(); 21297e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka mSuggestPuncs = puncs; 21306a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 21316a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani 2132979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean isSuggestedPunctuation(int code) { 2133979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return mSuggestPuncs.contains(String.valueOf((char)code)); 2134979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 2135979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 21362fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private void showSubtypeSelectorAndSettings() { 213785996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final CharSequence title = getString(R.string.english_ime_input_options); 213885996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final CharSequence[] items = new CharSequence[] { 213985996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka // TODO: Should use new string "Select active input modes". 214085996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka getString(R.string.language_selection_title), 214185996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka getString(R.string.english_ime_settings), 214285996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka }; 214385996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { 21442fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka @Override 21452fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka public void onClick(DialogInterface di, int position) { 21462fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka di.dismiss(); 21472fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka switch (position) { 214885996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka case 0: 21492cff4d7e4abdb192151f9b4027fc93fe28a8bdaasatok Intent intent = CompatUtils.getInputLanguageSelectionIntent( 21502cff4d7e4abdb192151f9b4027fc93fe28a8bdaasatok mInputMethodId, Intent.FLAG_ACTIVITY_NEW_TASK 21512fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 21522fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka | Intent.FLAG_ACTIVITY_CLEAR_TOP); 21532fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka startActivity(intent); 21542fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka break; 2155aa0458f917bb823efab6245f08c65e8f2f7327acKen Wakasa case 1: 2156aa0458f917bb823efab6245f08c65e8f2f7327acKen Wakasa launchSettings(); 2157aa0458f917bb823efab6245f08c65e8f2f7327acKen Wakasa break; 21582fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } 21592fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } 216085996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka }; 216185996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka showOptionsMenuInternal(title, items, listener); 21622fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } 2163923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 21642fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private void showOptionsMenu() { 216585996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final CharSequence title = getString(R.string.english_ime_input_options); 216685996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final CharSequence[] items = new CharSequence[] { 216785996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka getString(R.string.selectInputMethod), 216885996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka getString(R.string.english_ime_settings), 216985996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka }; 217085996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { 21715a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 2172923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onClick(DialogInterface di, int position) { 2173923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project di.dismiss(); 2174923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (position) { 217585996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka case 0: 2176ea55bf5df7d26d12b36c47141bfbac5730c3929aTadashi G. Takaoka mImm.showInputMethodPicker(); 21772fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka break; 217885996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka case 1: 2179ea55bf5df7d26d12b36c47141bfbac5730c3929aTadashi G. Takaoka launchSettings(); 21802fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka break; 2181923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2182923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 218385996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka }; 218485996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka showOptionsMenuInternal(title, items, listener); 21852fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } 21862fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka 218785996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka private void showOptionsMenuInternal(CharSequence title, CharSequence[] items, 218885996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka DialogInterface.OnClickListener listener) { 218918e15a1e5e30cf200e935e43a73edef25682de27Ken Wakasa final IBinder windowToken = mKeyboardSwitcher.getInputView().getWindowToken(); 219018e15a1e5e30cf200e935e43a73edef25682de27Ken Wakasa if (windowToken == null) return; 21912fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka AlertDialog.Builder builder = new AlertDialog.Builder(this); 21922fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka builder.setCancelable(true); 21932fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka builder.setIcon(R.drawable.ic_dialog_keyboard); 21942fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka builder.setNegativeButton(android.R.string.cancel, null); 219585996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka builder.setItems(items, listener); 219685996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka builder.setTitle(title); 2197923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mOptionsDialog = builder.create(); 2198a2ad96d95986eb61c3d2d5abce154fb4c3803cacTadashi G. Takaoka mOptionsDialog.setCanceledOnTouchOutside(true); 2199923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project Window window = mOptionsDialog.getWindow(); 2200923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project WindowManager.LayoutParams lp = window.getAttributes(); 220118e15a1e5e30cf200e935e43a73edef25682de27Ken Wakasa lp.token = windowToken; 2202923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 2203923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project window.setAttributes(lp); 2204923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); 2205923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mOptionsDialog.show(); 2206923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2207923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 22087e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka @Override 22097e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 2210923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.dump(fd, fout, args); 2211a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 2212923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final Printer p = new PrintWriterPrinter(fout); 2213923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println("LatinIME state :"); 2214923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" Keyboard mode = " + mKeyboardSwitcher.getKeyboardMode()); 2215923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mComposing=" + mComposing.toString()); 22169fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka p.println(" mIsSuggestionsRequested=" + mIsSettingsSuggestionStripOn); 2217923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mCorrectionMode=" + mCorrectionMode); 2218f108bf8fe924722ac6fc451f0235eb85a60f459dJean Chalard p.println(" mHasUncommittedTypedChars=" + mHasUncommittedTypedChars); 2219923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mAutoCorrectOn=" + mAutoCorrectOn); 22200730bbfbf5e37bbcb5c287aeff71b304c833a36eJean Chalard p.println(" mShouldInsertMagicSpace=" + mShouldInsertMagicSpace); 22211b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka p.println(" mApplicationSpecifiedCompletionOn=" + mApplicationSpecifiedCompletionOn); 2222923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" TextEntryState.state=" + TextEntryState.getState()); 2223923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mSoundOn=" + mSoundOn); 2224923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mVibrateOn=" + mVibrateOn); 2225979f8690967ff5409fe18f5085858ccdb8e0ccf1satok p.println(" mPopupOn=" + mPopupOn); 2226923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 22276e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani 2228923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Characters per second measurement 2229a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 2230923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private long mLastCpsTime; 2231923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private static final int CPS_BUFFER_SIZE = 16; 2232923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private long[] mCpsIntervals = new long[CPS_BUFFER_SIZE]; 2233923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mCpsIndex; 2234a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 2235923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void measureCps() { 2236923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project long now = System.currentTimeMillis(); 2237923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mLastCpsTime == 0) mLastCpsTime = now - 100; // Initial 2238923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCpsIntervals[mCpsIndex] = now - mLastCpsTime; 2239923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mLastCpsTime = now; 2240923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCpsIndex = (mCpsIndex + 1) % CPS_BUFFER_SIZE; 2241923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project long total = 0; 2242923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project for (int i = 0; i < CPS_BUFFER_SIZE; i++) total += mCpsIntervals[i]; 2243923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project System.out.println("CPS = " + ((CPS_BUFFER_SIZE * 1000f) / total)); 2244923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2245923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project} 2246