LatinIME.java revision 309bff562fbaf47488e6bf6636840f00574187d8
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; 285a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaokaimport com.android.inputmethod.keyboard.Keyboard; 295a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardActionListener; 30571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardSwitcher; 315a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardView; 32de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaokaimport com.android.inputmethod.keyboard.LatinKeyboard; 335a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaokaimport com.android.inputmethod.keyboard.LatinKeyboardView; 34388ce92ab8a635c5ad44620dad59baf05dfea510Amith Yamasani 35923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.app.AlertDialog; 36923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.BroadcastReceiver; 37923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.Context; 38923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.DialogInterface; 39923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.Intent; 40923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.IntentFilter; 41923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.SharedPreferences; 42923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.res.Configuration; 4336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.content.res.Resources; 44923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.inputmethodservice.InputMethodService; 45923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.media.AudioManager; 46123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaokaimport android.net.ConnectivityManager; 47923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.Debug; 48923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.Handler; 4918e15a1e5e30cf200e935e43a73edef25682de27Ken Wakasaimport android.os.IBinder; 50923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.Message; 51923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.SystemClock; 52bf96661d33d0126adb60a48880ceba1ff055d4a4satokimport android.preference.PreferenceActivity; 53923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.preference.PreferenceManager; 54e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaokaimport android.text.InputType; 55923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.text.TextUtils; 56979f8690967ff5409fe18f5085858ccdb8e0ccf1satokimport android.util.DisplayMetrics; 57923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.util.Log; 58923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.util.PrintWriterPrinter; 59923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.util.Printer; 6066a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasaniimport android.view.HapticFeedbackConstants; 61923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.KeyEvent; 62e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaokaimport android.view.LayoutInflater; 63923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.View; 648e09172df1bb176cc899940862c56bed9b9aec4esatokimport android.view.ViewGroup; 658e09172df1bb176cc899940862c56bed9b9aec4esatokimport android.view.ViewParent; 66923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.Window; 67923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.WindowManager; 68923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.inputmethod.CompletionInfo; 69923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.inputmethod.EditorInfo; 70466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport android.view.inputmethod.ExtractedText; 71466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport android.view.inputmethod.ExtractedTextRequest; 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; 77466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport java.util.ArrayList; 78b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimodaimport java.util.Arrays; 79466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport java.util.Locale; 80466741d8a78965b8509bf527344f289e50873092Mike LeBeau 81923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/** 82923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Input method implementation for Qwerty'ish keyboard. 83923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 8410dd34de0ffcde0104f7d2dae3a3c9fd66abffccsatokpublic class LatinIME extends InputMethodServiceCompatWrapper implements KeyboardActionListener { 858efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka private static final String TAG = LatinIME.class.getSimpleName(); 86979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private static final boolean PERF_DEBUG = false; 87409220583333bdf06290dd9fd42f91b5c0d1b11asatok private static final boolean TRACE = false; 88910b73127fa207dd26ec8124000262523b0aac0csatok private static boolean DEBUG = LatinImeLogger.sDBG; 89a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 908efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka /** 918efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka * The private IME option used to indicate that no microphone should be 928efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka * shown for a given text field. For instance, this is specified by the 938efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka * search dialog when the dialog is already showing a voice search button. 948efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka * 958efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka * @deprecated Use {@link LatinIME#IME_OPTION_NO_MICROPHONE} with package name prefixed. 968efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka */ 9710dd34de0ffcde0104f7d2dae3a3c9fd66abffccsatok @SuppressWarnings("dep-ann") 988efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka public static final String IME_OPTION_NO_MICROPHONE_COMPAT = "nm"; 998efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka 1008efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka /** 1018efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka * The private IME option used to indicate that no microphone should be 1028efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka * shown for a given text field. For instance, this is specified by the 1038efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka * search dialog when the dialog is already showing a voice search button. 1048efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka */ 1054199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka public static final String IME_OPTION_NO_MICROPHONE = "noMicrophoneKey"; 1064199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka 1074199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka /** 1084199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka * The private IME option used to indicate that no settings key should be 1094199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka * shown for a given text field. 1104199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka */ 1114199e29a7d796191d3e13ef07e6e80e91834fe7aTadashi G. Takaoka public static final String IME_OPTION_NO_SETTINGS_KEY = "noSettingsKey"; 1128efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka 113fd0bd57deb53c4cce32810a61133fa44b45dbb7bKen Wakasa private static final int DELAY_UPDATE_SUGGESTIONS = 180; 114fd0bd57deb53c4cce32810a61133fa44b45dbb7bKen Wakasa private static final int DELAY_UPDATE_OLD_SUGGESTIONS = 300; 115d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int DELAY_UPDATE_SHIFT_STATE = 300; 1169e347d3d448e48229c46aad394ec9bd60cd5807bsatok private static final int EXTENDED_TOUCHABLE_REGION_HEIGHT = 100; 117fd0bd57deb53c4cce32810a61133fa44b45dbb7bKen Wakasa 118923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // How many continuous deletes at which to start deleting at a higher speed. 119923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private static final int DELETE_ACCELERATE_AT = 20; 120923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Key events coming any faster than this are long-presses. 121d67fe0e7583f1be18b35b33b7658e4427f1e3dedAmith Yamasani private static final int QUICK_PRESS = 200; 122a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 123cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard /** 124cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard * The name of the scheme used by the Package Manager to warn of a new package installation, 125cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard * replacement or removal. 126cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard */ 127cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard private static final String SCHEME_PACKAGE = "package"; 128cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard 1297599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private int mSuggestionVisibility; 1307599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private static final int SUGGESTION_VISIBILILTY_SHOW_VALUE 1317599cfea4a2d56f4779452ec8e8742f7b9629cc0satok = R.string.prefs_suggestion_visibility_show_value; 1327599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private static final int SUGGESTION_VISIBILILTY_SHOW_ONLY_PORTRAIT_VALUE 1337599cfea4a2d56f4779452ec8e8742f7b9629cc0satok = R.string.prefs_suggestion_visibility_show_only_portrait_value; 1347599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private static final int SUGGESTION_VISIBILILTY_HIDE_VALUE 1357599cfea4a2d56f4779452ec8e8742f7b9629cc0satok = R.string.prefs_suggestion_visibility_hide_value; 1367599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 1377599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private static final int[] SUGGESTION_VISIBILITY_VALUE_ARRAY = new int[] { 1387599cfea4a2d56f4779452ec8e8742f7b9629cc0satok SUGGESTION_VISIBILILTY_SHOW_VALUE, 1397599cfea4a2d56f4779452ec8e8742f7b9629cc0satok SUGGESTION_VISIBILILTY_SHOW_ONLY_PORTRAIT_VALUE, 1407599cfea4a2d56f4779452ec8e8742f7b9629cc0satok SUGGESTION_VISIBILILTY_HIDE_VALUE 1417599cfea4a2d56f4779452ec8e8742f7b9629cc0satok }; 1427599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 143e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka private View mCandidateViewContainer; 1447a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka private int mCandidateStripHeight; 145923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private CandidateView mCandidateView; 146923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private Suggest mSuggest; 1471b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka private CompletionInfo[] mApplicationSpecifiedCompletions; 148a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 149923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private AlertDialog mOptionsDialog; 150a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 151610f1dc8553cf2ed97e763a06a19380c4a6cd636satok private InputMethodManagerCompatWrapper mImm; 1522fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private Resources mResources; 1532fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private SharedPreferences mPrefs; 1542fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private String mInputMethodId; 15571c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka private KeyboardSwitcher mKeyboardSwitcher; 1560ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private SubtypeSwitcher mSubtypeSwitcher; 157b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok private VoiceProxy mVoiceProxy; 158a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 159923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private UserDictionary mUserDictionary; 160979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private UserBigramDictionary mUserBigramDictionary; 1612bed1531c2c9bd48096bfa97dd1a39e04bd15e7bEric Fischer private ContactsDictionary mContactsDictionary; 1624ff60be170872503cca0275ef3488b7379b5311bAmith Yamasani private AutoDictionary mAutoDictionary; 16336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 164c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // These variables are initialized according to the {@link EditorInfo#inputType}. 165c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka private boolean mAutoSpace; 166c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka private boolean mInputTypeNoAutoCorrect; 167c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka private boolean mIsSettingsSuggestionStripOn; 168c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka private boolean mApplicationSpecifiedCompletionOn; 169c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 170dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette private AccessibilityUtils mAccessibilityUtils; 171dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette 17271c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka private final StringBuilder mComposing = new StringBuilder(); 173923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private WordComposer mWord = new WordComposer(); 174923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private CharSequence mBestWord; 1759fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka private boolean mHasValidSuggestions; 176e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani private boolean mHasDictionary; 1779a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa private boolean mJustAddedAutoSpace; 178e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani private boolean mAutoCorrectEnabled; 179952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa private boolean mRecorrectionEnabled; 180b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard // Suggestion: use bigrams to adjust scores of suggestions obtained from unigram dictionary 181979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean mBigramSuggestionEnabled; 182b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard // Prediction: use bigrams to predict the next word when there is no input for it yet 183b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard private boolean mBigramPredictionEnabled; 184923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mAutoCorrectOn; 185923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mVibrateOn; 186923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mSoundOn; 187979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean mPopupOn; 188923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mAutoCap; 1896e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani private boolean mQuickFixes; 1902fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private boolean mConfigEnableShowSubtypeSettings; 191363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka private boolean mConfigSwipeDownDismissKeyboardEnabled; 192de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka private int mConfigDelayBeforeFadeoutLanguageOnSpacebar; 193de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka private int mConfigDurationOfFadeoutLanguageOnSpacebar; 194d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka private float mConfigFinalFadeoutFactorOfLanguageOnSpacebar; 195fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka private long mConfigDoubleSpacesTurnIntoPeriodTimeout; 196409220583333bdf06290dd9fd42f91b5c0d1b11asatok 19779efbed76f638be298493107fa2d0cd1b5eb529esatok private int mCorrectionMode; 19879efbed76f638be298493107fa2d0cd1b5eb529esatok private int mCommittedLength; 19979efbed76f638be298493107fa2d0cd1b5eb529esatok private int mOrientation; 200979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Keep track of the last selection range to decide if we need to show word alternatives 20179efbed76f638be298493107fa2d0cd1b5eb529esatok private int mLastSelectionStart; 20279efbed76f638be298493107fa2d0cd1b5eb529esatok private int mLastSelectionEnd; 2037e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka private SuggestedWords mSuggestPuncList; 204979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 205923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Indicates whether the suggestion strip is to be on in landscape 206923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mJustAccepted; 207923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mDeleteCount; 208923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private long mLastKeyTime; 209a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 210923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private AudioManager mAudioManager; 2112296317b8f0209789f797ac8a2fcb70e03f6d001Eric Laurent // Align sound effect volume on music volume 21271c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka private static final float FX_VOLUME = -1.0f; 213923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean mSilentMode; 214923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 215979f8690967ff5409fe18f5085858ccdb8e0ccf1satok /* package */ String mWordSeparators; 216923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private String mSentenceSeparators; 217979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private String mSuggestPuncs; 218b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok // TODO: Move this flag to VoiceProxy 21981c52293f84ce475ac6b1661f4a4b92703405247Amith Yamasani private boolean mConfigurationChanging; 220466741d8a78965b8509bf527344f289e50873092Mike LeBeau 221cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard // Object for reacting to adding/removing a dictionary pack. 222cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard private BroadcastReceiver mDictionaryPackInstallReceiver = 223cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard new DictionaryPackInstallBroadcastReceiver(this); 224cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard 225dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani // Keeps track of most recently inserted text (multi-character key) for reverting 226dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani private CharSequence mEnteredText; 227dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani 22871c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka private final ArrayList<WordAlternatives> mWordHistory = new ArrayList<WordAlternatives>(); 229979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 230071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka public class WordAlternatives { 231071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka private final CharSequence mChosenWord; 232071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka private final WordComposer mWordComposer; 2334f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 234071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka public WordAlternatives(CharSequence chosenWord, WordComposer wordComposer) { 235979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mChosenWord = chosenWord; 236071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka mWordComposer = wordComposer; 237979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 238979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 239979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public CharSequence getChosenWord() { 240979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return mChosenWord; 241979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 242979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 243071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka public CharSequence getOriginalWord() { 244071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka return mWordComposer.getTypedWord(); 245979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 246979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 247071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka public SuggestedWords.Builder getAlternatives() { 248071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka return getTypedSuggestions(mWordComposer); 249979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 250979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 251979f8690967ff5409fe18f5085858ccdb8e0ccf1satok @Override 252071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka public int hashCode() { 253071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka return mChosenWord.hashCode(); 254979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 255979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 256979f8690967ff5409fe18f5085858ccdb8e0ccf1satok @Override 257071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka public boolean equals(Object o) { 258071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka return o instanceof CharSequence && TextUtils.equals(mChosenWord, (CharSequence)o); 259979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 260979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 26136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 262571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka public final UIHandler mHandler = new UIHandler(); 263d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 264409220583333bdf06290dd9fd42f91b5c0d1b11asatok public class UIHandler extends Handler { 265d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int MSG_UPDATE_SUGGESTIONS = 0; 266d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int MSG_UPDATE_OLD_SUGGESTIONS = 1; 267d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int MSG_UPDATE_SHIFT_STATE = 2; 268d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka private static final int MSG_VOICE_RESULTS = 3; 269de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka private static final int MSG_FADEOUT_LANGUAGE_ON_SPACEBAR = 4; 270de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka private static final int MSG_DISMISS_LANGUAGE_ON_SPACEBAR = 5; 271fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka private static final int MSG_SPACE_TYPED = 6; 272cb3320179d39a7983874697a0aa428b127675c9dJean Chalard private static final int MSG_SET_BIGRAM_PREDICTIONS = 7; 273d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 274923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 275923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void handleMessage(Message msg) { 276de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka final KeyboardSwitcher switcher = mKeyboardSwitcher; 277de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka final LatinKeyboardView inputView = switcher.getInputView(); 278923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (msg.what) { 279d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka case MSG_UPDATE_SUGGESTIONS: 280d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka updateSuggestions(); 281d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 282d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka case MSG_UPDATE_OLD_SUGGESTIONS: 283d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka setOldSuggestions(); 284d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 285d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka case MSG_UPDATE_SHIFT_STATE: 286de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka switcher.updateShiftState(); 287d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 288cb3320179d39a7983874697a0aa428b127675c9dJean Chalard case MSG_SET_BIGRAM_PREDICTIONS: 289cb3320179d39a7983874697a0aa428b127675c9dJean Chalard updateBigramPredictions(); 29089bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard break; 291d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka case MSG_VOICE_RESULTS: 292b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.handleVoiceResults(preferCapitalization() 293de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka || (switcher.isAlphabetMode() && switcher.isShiftedOrShiftLocked())); 294de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka break; 295de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka case MSG_FADEOUT_LANGUAGE_ON_SPACEBAR: 296de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (inputView != null) 29766432cfc9b7680a653bcf19d0d4250db21155eceTadashi G. Takaoka inputView.setSpacebarTextFadeFactor( 298d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka (1.0f + mConfigFinalFadeoutFactorOfLanguageOnSpacebar) / 2, 29966432cfc9b7680a653bcf19d0d4250db21155eceTadashi G. Takaoka (LatinKeyboard)msg.obj); 300de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_DISMISS_LANGUAGE_ON_SPACEBAR, msg.obj), 301de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka mConfigDurationOfFadeoutLanguageOnSpacebar); 302de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka break; 303de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka case MSG_DISMISS_LANGUAGE_ON_SPACEBAR: 304de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (inputView != null) 30566432cfc9b7680a653bcf19d0d4250db21155eceTadashi G. Takaoka inputView.setSpacebarTextFadeFactor( 306d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka mConfigFinalFadeoutFactorOfLanguageOnSpacebar, (LatinKeyboard)msg.obj); 307d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 308923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 309923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 310d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 311d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void postUpdateSuggestions() { 312d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_SUGGESTIONS); 313d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTIONS), DELAY_UPDATE_SUGGESTIONS); 314d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 315d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 316d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void cancelUpdateSuggestions() { 317d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_SUGGESTIONS); 318d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 319d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 320d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public boolean hasPendingUpdateSuggestions() { 321d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka return hasMessages(MSG_UPDATE_SUGGESTIONS); 322d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 323d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 324d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void postUpdateOldSuggestions() { 325d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_OLD_SUGGESTIONS); 326d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_UPDATE_OLD_SUGGESTIONS), 327d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka DELAY_UPDATE_OLD_SUGGESTIONS); 328d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 329d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 330d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void cancelUpdateOldSuggestions() { 331d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_OLD_SUGGESTIONS); 332d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 333d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 334d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void postUpdateShiftKeyState() { 335d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_SHIFT_STATE); 336d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE), DELAY_UPDATE_SHIFT_STATE); 337d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 338d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 339d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void cancelUpdateShiftState() { 340d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_SHIFT_STATE); 341d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 342d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 343cb3320179d39a7983874697a0aa428b127675c9dJean Chalard public void postUpdateBigramPredictions() { 344cb3320179d39a7983874697a0aa428b127675c9dJean Chalard removeMessages(MSG_SET_BIGRAM_PREDICTIONS); 345cb3320179d39a7983874697a0aa428b127675c9dJean Chalard sendMessageDelayed(obtainMessage(MSG_SET_BIGRAM_PREDICTIONS), DELAY_UPDATE_SUGGESTIONS); 34689bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 34789bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard 348cb3320179d39a7983874697a0aa428b127675c9dJean Chalard public void cancelUpdateBigramPredictions() { 349cb3320179d39a7983874697a0aa428b127675c9dJean Chalard removeMessages(MSG_SET_BIGRAM_PREDICTIONS); 35089bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 35189bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard 352d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public void updateVoiceResults() { 353d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka sendMessage(obtainMessage(MSG_VOICE_RESULTS)); 354d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 355de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka 356d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka public void startDisplayLanguageOnSpacebar(boolean localeChanged) { 357de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka removeMessages(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR); 358de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka removeMessages(MSG_DISMISS_LANGUAGE_ON_SPACEBAR); 359de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka final LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); 360de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (inputView != null) { 361050c0462dc2ada5a5afecec5b6745693c5066b85Tadashi G. Takaoka final LatinKeyboard keyboard = mKeyboardSwitcher.getLatinKeyboard(); 362c5c57b506e97b334a394d23ed73c9597cb55707aTadashi G. Takaoka // The language is always displayed when the delay is negative. 363c5c57b506e97b334a394d23ed73c9597cb55707aTadashi G. Takaoka final boolean needsToDisplayLanguage = localeChanged 364c5c57b506e97b334a394d23ed73c9597cb55707aTadashi G. Takaoka || mConfigDelayBeforeFadeoutLanguageOnSpacebar < 0; 365de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka // The language is never displayed when the delay is zero. 366de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka if (mConfigDelayBeforeFadeoutLanguageOnSpacebar != 0) 367c5c57b506e97b334a394d23ed73c9597cb55707aTadashi G. Takaoka inputView.setSpacebarTextFadeFactor(needsToDisplayLanguage ? 1.0f 368d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka : mConfigFinalFadeoutFactorOfLanguageOnSpacebar, keyboard); 369c5c57b506e97b334a394d23ed73c9597cb55707aTadashi G. Takaoka // The fadeout animation will start when the delay is positive. 370d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka if (localeChanged && mConfigDelayBeforeFadeoutLanguageOnSpacebar > 0) { 371de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR, keyboard), 372de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka mConfigDelayBeforeFadeoutLanguageOnSpacebar); 373de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka } 374de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka } 375de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka } 376fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka 377fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka public void startDoubleSpacesTimer() { 378fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka removeMessages(MSG_SPACE_TYPED); 379fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_SPACE_TYPED), 380fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka mConfigDoubleSpacesTurnIntoPeriodTimeout); 381fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka } 382fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka 383fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka public void cancelDoubleSpacesTimer() { 384fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka removeMessages(MSG_SPACE_TYPED); 385fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka } 386fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka 387fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka public boolean isAcceptingDoubleSpaces() { 388fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka return hasMessages(MSG_SPACE_TYPED); 389fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka } 390d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 391923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 3927e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka @Override 3937e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka public void onCreate() { 39427d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); 39527d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa mPrefs = prefs; 39627d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa LatinImeLogger.init(this, prefs); 3976d9021527a38ba1e94225020389621a0d7227aa1satok LanguageSwitcherProxy.init(this, prefs); 39827d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa SubtypeSwitcher.init(this, prefs); 39927d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa KeyboardSwitcher.init(this, prefs); 400dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette AccessibilityUtils.init(this, prefs); 401363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka 402923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onCreate(); 403363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka 404610f1dc8553cf2ed97e763a06a19380c4a6cd636satok mImm = InputMethodManagerCompatWrapper.getInstance(this); 4058efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka mInputMethodId = Utils.getInputMethodId(mImm, getPackageName()); 4060ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mSubtypeSwitcher = SubtypeSwitcher.getInstance(); 4070ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok mKeyboardSwitcher = KeyboardSwitcher.getInstance(); 408dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette mAccessibilityUtils = AccessibilityUtils.getInstance(); 409363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka 410363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka final Resources res = getResources(); 411363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka mResources = res; 412fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard 413fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard // If the option should not be shown, do not read the recorrection preference 414fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard // but always use the default setting defined in the resources. 415fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard if (res.getBoolean(R.bool.config_enable_show_recorrection_option)) { 416952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa mRecorrectionEnabled = prefs.getBoolean(Settings.PREF_RECORRECTION_ENABLED, 417f0d99b8677afdde39c16d414d44bfafcaea94b50Jean Chalard res.getBoolean(R.bool.config_default_recorrection_enabled)); 418fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard } else { 419952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa mRecorrectionEnabled = res.getBoolean(R.bool.config_default_recorrection_enabled); 420fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard } 421fd7d814c81132bdd59146a39dd668532f9514cd1Jean Chalard 4222fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka mConfigEnableShowSubtypeSettings = res.getBoolean( 4232fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka R.bool.config_enable_show_subtype_settings); 424363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka mConfigSwipeDownDismissKeyboardEnabled = res.getBoolean( 425363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka R.bool.config_swipe_down_dismiss_keyboard_enabled); 426de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka mConfigDelayBeforeFadeoutLanguageOnSpacebar = res.getInteger( 427de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka R.integer.config_delay_before_fadeout_language_on_spacebar); 428de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka mConfigDurationOfFadeoutLanguageOnSpacebar = res.getInteger( 429de0c8874a4eb1250e8439d9e4e1badca88316670Tadashi G. Takaoka R.integer.config_duration_of_fadeout_language_on_spacebar); 430d5a6b910e83de6dea3c5813cbf5e219abaccdf8aTadashi G. Takaoka mConfigFinalFadeoutFactorOfLanguageOnSpacebar = res.getInteger( 43166432cfc9b7680a653bcf19d0d4250db21155eceTadashi G. Takaoka R.integer.config_final_fadeout_percentage_of_language_on_spacebar) / 100.0f; 432fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka mConfigDoubleSpacesTurnIntoPeriodTimeout = res.getInteger( 433fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka R.integer.config_double_spaces_turn_into_period_timeout); 434979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 4359502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka Utils.GCUtils.getInstance().reset(); 436979f8690967ff5409fe18f5085858ccdb8e0ccf1satok boolean tryGC = true; 4379502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) { 438979f8690967ff5409fe18f5085858ccdb8e0ccf1satok try { 4390ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok initSuggest(); 440979f8690967ff5409fe18f5085858ccdb8e0ccf1satok tryGC = false; 441979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } catch (OutOfMemoryError e) { 4429502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka tryGC = Utils.GCUtils.getInstance().tryGCOrWait("InitSuggest", e); 443979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 444979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 445979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 446363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka mOrientation = res.getConfiguration().orientation; 4476a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani initSuggestPuncList(); 448b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani 449cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard // Register to receive ringer mode change and network state change. 450cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard // Also receive installation and removal of a dictionary pack. 451123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka final IntentFilter filter = new IntentFilter(); 452123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); 453123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 454923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project registerReceiver(mReceiver, filter); 455b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy = VoiceProxy.init(this, prefs, mHandler); 456cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard 457cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard final IntentFilter packageFilter = new IntentFilter(); 458cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 459cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 460cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard packageFilter.addDataScheme(SCHEME_PACKAGE); 461cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard registerReceiver(mDictionaryPackInstallReceiver, packageFilter); 462646d950ed8d2b2555df92855e18b350fd7761b21Jean Chalard 463646d950ed8d2b2555df92855e18b350fd7761b21Jean Chalard final IntentFilter newDictFilter = new IntentFilter(); 464646d950ed8d2b2555df92855e18b350fd7761b21Jean Chalard newDictFilter.addAction( 465646d950ed8d2b2555df92855e18b350fd7761b21Jean Chalard DictionaryPackInstallBroadcastReceiver.NEW_DICTIONARY_INTENT_ACTION); 466646d950ed8d2b2555df92855e18b350fd7761b21Jean Chalard registerReceiver(mDictionaryPackInstallReceiver, newDictFilter); 467923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 46836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 4690ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private void initSuggest() { 470cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard final String localeStr = mSubtypeSwitcher.getInputLocaleStr(); 471cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard final Locale keyboardLocale = new Locale(localeStr); 47236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 473309bff562fbaf47488e6bf6636840f00574187d8Jean Chalard final Resources res = mResources; 474309bff562fbaf47488e6bf6636840f00574187d8Jean Chalard final Locale savedLocale = Utils.setSystemLocale(res, keyboardLocale); 47536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani if (mSuggest != null) { 47636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani mSuggest.close(); 47736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 47827d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa final SharedPreferences prefs = mPrefs; 47989764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard mQuickFixes = isQuickFixesEnabled(prefs); 480979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 4818efc0addce3cd1a32618bf18bafabaaca2b498b0Tadashi G. Takaoka int mainDicResId = Utils.getMainDictionaryResourceId(res); 482cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard mSuggest = new Suggest(this, mainDicResId, keyboardLocale); 4831b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka loadAndSetAutoCorrectionThreshold(prefs); 48427023341658b4cf5430d18ddb94fd9502ecfe3cbTadashi G. Takaoka updateAutoTextEnabled(); 485e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 486cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard mUserDictionary = new UserDictionary(this, localeStr); 487923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSuggest.setUserDictionary(mUserDictionary); 488e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 489e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mContactsDictionary = new ContactsDictionary(this, Suggest.DIC_CONTACTS); 4902bed1531c2c9bd48096bfa97dd1a39e04bd15e7bEric Fischer mSuggest.setContactsDictionary(mContactsDictionary); 491e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 492cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard mAutoDictionary = new AutoDictionary(this, this, localeStr, Suggest.DIC_AUTO); 49334386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani mSuggest.setAutoDictionary(mAutoDictionary); 494e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 495cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard mUserBigramDictionary = new UserBigramDictionary(this, this, localeStr, Suggest.DIC_USER); 496e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mSuggest.setUserBigramDictionary(mUserBigramDictionary); 497e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa 498e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani updateCorrectionMode(); 499458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa mWordSeparators = res.getString(R.string.word_separators); 500458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa mSentenceSeparators = res.getString(R.string.sentence_separators); 50136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 502309bff562fbaf47488e6bf6636840f00574187d8Jean Chalard Utils.setSystemLocale(res, savedLocale); 503923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 50436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 505cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard /* package private */ void resetSuggestMainDict() { 506cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard final String localeStr = mSubtypeSwitcher.getInputLocaleStr(); 507cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard final Locale keyboardLocale = new Locale(localeStr); 508cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard int mainDicResId = Utils.getMainDictionaryResourceId(mResources); 509cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard mSuggest.resetMainDict(this, mainDicResId, keyboardLocale); 510cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard } 511cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard 512466741d8a78965b8509bf527344f289e50873092Mike LeBeau @Override 513466741d8a78965b8509bf527344f289e50873092Mike LeBeau public void onDestroy() { 514e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa if (mSuggest != null) { 515e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mSuggest.close(); 516e90b333017c68e888a5e3d351f07ea29036457d0Ken Wakasa mSuggest = null; 517979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 518923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project unregisterReceiver(mReceiver); 519cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard unregisterReceiver(mDictionaryPackInstallReceiver); 520b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.destroy(); 521979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.commit(); 522979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.onDestroy(); 523923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onDestroy(); 524923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 525923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 526923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 527923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onConfigurationChanged(Configuration conf) { 528dc64b138b5e3fb3706c0818d0a308fe6e36985b0Tadashi G. Takaoka mSubtypeSwitcher.onConfigurationChanged(conf); 529b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani // If orientation changed while predicting, commit the change 530b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani if (conf.orientation != mOrientation) { 531466741d8a78965b8509bf527344f289e50873092Mike LeBeau InputConnection ic = getCurrentInputConnection(); 532466741d8a78965b8509bf527344f289e50873092Mike LeBeau commitTyped(ic); 533466741d8a78965b8509bf527344f289e50873092Mike LeBeau if (ic != null) ic.finishComposingText(); // For voice input 534b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani mOrientation = conf.orientation; 5352fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka if (isShowingOptionDialog()) 5362fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka mOptionsDialog.dismiss(); 537b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani } 5388b00bc4f3281c229ee830f34a78c0ec287902c3fTadashi G. Takaoka 53981c52293f84ce475ac6b1661f4a4b92703405247Amith Yamasani mConfigurationChanging = true; 540923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onConfigurationChanged(conf); 541b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.onConfigurationChanged(conf); 54281c52293f84ce475ac6b1661f4a4b92703405247Amith Yamasani mConfigurationChanging = false; 54388fc9d44186120f9edc5cf7ec0e2af85260fed04satok 54488fc9d44186120f9edc5cf7ec0e2af85260fed04satok // This will work only when the subtype is not supported. 54588fc9d44186120f9edc5cf7ec0e2af85260fed04satok LanguageSwitcherProxy.onConfigurationChanged(conf); 546923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 547b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani 548923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 549923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public View onCreateInputView() { 5508d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka return mKeyboardSwitcher.onCreateInputView(); 551923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 552923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 553923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 554923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public View onCreateCandidatesView() { 555e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka LayoutInflater inflater = getLayoutInflater(); 556e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka LinearLayout container = (LinearLayout)inflater.inflate(R.layout.candidates, null); 557e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka mCandidateViewContainer = container; 5587a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka mCandidateStripHeight = (int)mResources.getDimension(R.dimen.candidate_strip_height); 559e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka mCandidateView = (CandidateView) container.findViewById(R.id.candidates); 560923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCandidateView.setService(this); 561923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project setCandidatesViewShown(true); 562e49bd1c43acad08f103b38430a8bbcba23f325b3Tadashi G. Takaoka return container; 563923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 564923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 565a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker @Override 566923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onStartInputView(EditorInfo attribute, boolean restarting) { 56745911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final KeyboardSwitcher switcher = mKeyboardSwitcher; 56845911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka LatinKeyboardView inputView = switcher.getInputView(); 5698e09172df1bb176cc899940862c56bed9b9aec4esatok 57089bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (DEBUG) { 571910b73127fa207dd26ec8124000262523b0aac0csatok Log.d(TAG, "onStartInputView: " + inputView); 572910b73127fa207dd26ec8124000262523b0aac0csatok } 573923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // In landscape mode, this method gets called without the input view being created. 574979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (inputView == null) { 575923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 576923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 577923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 5788d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka mSubtypeSwitcher.updateParametersOnStartInputView(); 5794ab730dbd34fad323063f2ffd31ce33de746668dsatok 580662bb7c26cadd5026cb3d4e5d081aae163bd5a3aTadashi G. Takaoka TextEntryState.reset(); 5816c7c8f5b477e7aea207d41417092e8b92db2e24fAmith Yamasani 582c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // Most such things we decide below in initializeInputAttributesAndGetMode, but we need to 583c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // know now whether this is a password text field, because we need to know now whether we 584c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // want to enable the voice button. 585b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok final VoiceProxy voiceIme = mVoiceProxy; 586e9957752bcaad048746c7a57bbd2c0a59e1918a0satok voiceIme.resetVoiceStates(InputTypeCompatUtils.isPasswordInputType(attribute.inputType) 587e9957752bcaad048746c7a57bbd2c0a59e1918a0satok || InputTypeCompatUtils.isVisiblePasswordInputType(attribute.inputType)); 588c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 589cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka initializeInputAttributes(attribute); 590c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 591c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka inputView.closing(); 592c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mEnteredText = null; 593c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mComposing.setLength(0); 594c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mHasValidSuggestions = false; 595c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mDeleteCount = 0; 596c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mJustAddedAutoSpace = false; 597c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 598c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka loadSettings(attribute); 599c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka if (mSubtypeSwitcher.isKeyboardMode()) { 600cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka switcher.loadKeyboard(attribute, 6014503e2ea9853c1573f60903d8639d82e39e07c56Tadashi G. Takaoka mSubtypeSwitcher.isShortcutImeEnabled() && voiceIme.isVoiceButtonEnabled(), 6024503e2ea9853c1573f60903d8639d82e39e07c56Tadashi G. Takaoka voiceIme.isVoiceButtonOnPrimary()); 603c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka switcher.updateShiftState(); 604c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka } 605c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 6067a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka setCandidatesViewShownInternal(isCandidateStripVisible(), false /* needsInputViewShown */ ); 607c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // Delay updating suggestions because keyboard input view may not be shown at this point. 608c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mHandler.postUpdateSuggestions(); 609c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 610c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka updateCorrectionMode(); 611c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 612dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette final boolean accessibilityEnabled = mAccessibilityUtils.isAccessibilityEnabled(); 613dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette 614d9786ce2e389c8c02af7773b53b5c44fe4fa0b0cTadashi G. Takaoka inputView.setKeyPreviewEnabled(mPopupOn); 615c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka inputView.setProximityCorrectionEnabled(true); 616dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette inputView.setAccessibilityEnabled(accessibilityEnabled); 617c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // If we just entered a text field, maybe it has some old text that requires correction 618952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa checkRecorrectionOnStart(); 619c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka inputView.setForeground(true); 620c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 6214503e2ea9853c1573f60903d8639d82e39e07c56Tadashi G. Takaoka voiceIme.onStartInputView(inputView.getWindowToken()); 622c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 623c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); 624c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka } 625c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 626cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka private void initializeInputAttributes(EditorInfo attribute) { 627cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka if (attribute == null) 628cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka return; 6294b13b4f94215368c6387b2564bdaf2cbcbe4c130Tadashi G. Takaoka final int inputType = attribute.inputType; 630c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka final int variation = inputType & InputType.TYPE_MASK_VARIATION; 631c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka mAutoSpace = false; 632e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mInputTypeNoAutoCorrect = false; 6339fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 6341b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mApplicationSpecifiedCompletionOn = false; 6351b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mApplicationSpecifiedCompletions = null; 636dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani 637cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka if ((inputType & InputType.TYPE_MASK_CLASS) == InputType.TYPE_CLASS_TEXT) { 638cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mIsSettingsSuggestionStripOn = true; 639cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka // Make sure that passwords are not displayed in candidate view 640e9957752bcaad048746c7a57bbd2c0a59e1918a0satok if (InputTypeCompatUtils.isPasswordInputType(inputType) 641e9957752bcaad048746c7a57bbd2c0a59e1918a0satok || InputTypeCompatUtils.isVisiblePasswordInputType(inputType)) { 642cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 643cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } 644e9957752bcaad048746c7a57bbd2c0a59e1918a0satok if (InputTypeCompatUtils.isEmailVariation(variation) 645cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka || variation == InputType.TYPE_TEXT_VARIATION_PERSON_NAME) { 646cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mAutoSpace = false; 647cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } else { 648cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mAutoSpace = true; 649cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } 650e9957752bcaad048746c7a57bbd2c0a59e1918a0satok if (InputTypeCompatUtils.isEmailVariation(variation)) { 651cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 652cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } else if (variation == InputType.TYPE_TEXT_VARIATION_URI) { 653cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 654cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } else if (variation == InputType.TYPE_TEXT_VARIATION_FILTER) { 655cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 656cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } else if (variation == InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) { 657cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka // If it's a browser edit field and auto correct is not ON explicitly, then 658cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka // disable auto correction, but keep suggestions on. 659cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) { 660e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mInputTypeNoAutoCorrect = true; 66136ebae2e8d58d36d3f8dd2f8a2d34c0c06522a8eAmith Yamasani } 662cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } 663cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka 664cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka // If NO_SUGGESTIONS is set, don't do prediction. 665cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka if ((inputType & InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) { 666cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 667cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mInputTypeNoAutoCorrect = true; 668cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } 669cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka // If it's not multiline and the autoCorrect flag is not set, then don't correct 670cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 671cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka && (inputType & InputType.TYPE_TEXT_FLAG_MULTI_LINE) == 0) { 672cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mInputTypeNoAutoCorrect = true; 673cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } 674cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka if ((inputType & InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) { 675cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mIsSettingsSuggestionStripOn = false; 676cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mApplicationSpecifiedCompletionOn = isFullscreenMode(); 677cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka } 678923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 679923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 680923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 681952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa private void checkRecorrectionOnStart() { 682952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa if (!mRecorrectionEnabled) return; 683d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa 684d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa final InputConnection ic = getCurrentInputConnection(); 685d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa if (ic == null) return; 686d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa // There could be a pending composing span. Clean it up first. 687d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa ic.finishComposingText(); 688d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa 6899fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (isShowingSuggestionsStrip() && isSuggestionsRequested()) { 690b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani // First get the cursor position. This is required by setOldSuggestions(), so that 691b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani // it can pass the correct range to setComposingRegion(). At this point, we don't 6924ca16dbd65150359c3884da7cb59a30f19abd4b7Tadashi G. Takaoka // have valid values for mLastSelectionStart/End because onUpdateSelection() has 693b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani // not been called yet. 694b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani ExtractedTextRequest etr = new ExtractedTextRequest(); 695b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani etr.token = 0; // anything is fine here 696b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani ExtractedText et = ic.getExtractedText(etr, 0); 697b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani if (et == null) return; 698b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani 699b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani mLastSelectionStart = et.startOffset + et.selectionStart; 700b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani mLastSelectionEnd = et.startOffset + et.selectionEnd; 701b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani 702b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani // Then look for possible corrections in a delayed fashion 70355b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa if (!TextUtils.isEmpty(et.text) && isCursorTouchingWord()) { 704d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateOldSuggestions(); 70555b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa } 706b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani } 707b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani } 708b8fa10080dfac777fce7c8a7fc3180e8b540f9f5Amith Yamasani 709923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 710923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onFinishInput() { 711923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onFinishInput(); 712a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 713979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.commit(); 7141b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mKeyboardSwitcher.onAutoCorrectionStateChanged(false); 715979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 716b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.flushVoiceInputLogs(mConfigurationChanging); 717409220583333bdf06290dd9fd42f91b5c0d1b11asatok 7185a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka KeyboardView inputView = mKeyboardSwitcher.getInputView(); 719d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa if (inputView != null) inputView.closing(); 7204ff60be170872503cca0275ef3488b7379b5311bAmith Yamasani if (mAutoDictionary != null) mAutoDictionary.flushPendingWrites(); 721979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mUserBigramDictionary != null) mUserBigramDictionary.flushPendingWrites(); 722466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 723466741d8a78965b8509bf527344f289e50873092Mike LeBeau 724466741d8a78965b8509bf527344f289e50873092Mike LeBeau @Override 7256495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa public void onFinishInputView(boolean finishingInput) { 7266495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa super.onFinishInputView(finishingInput); 7275a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka KeyboardView inputView = mKeyboardSwitcher.getInputView(); 728d024ea605cc6b5b0b9fa1bd838d5b0ebd3901a5dKen Wakasa if (inputView != null) inputView.setForeground(false); 729d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka // Remove pending messages related to update suggestions 730d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.cancelUpdateSuggestions(); 731d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.cancelUpdateOldSuggestions(); 7326495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa } 7336495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa 7346495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa @Override 735466741d8a78965b8509bf527344f289e50873092Mike LeBeau public void onUpdateExtractedText(int token, ExtractedText text) { 736466741d8a78965b8509bf527344f289e50873092Mike LeBeau super.onUpdateExtractedText(token, text); 737b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.showPunctuationHintIfNecessary(); 738923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 739923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 740923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 741923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onUpdateSelection(int oldSelStart, int oldSelEnd, 742923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int newSelStart, int newSelEnd, 743923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int candidatesStart, int candidatesEnd) { 744923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, 745923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project candidatesStart, candidatesEnd); 746466741d8a78965b8509bf527344f289e50873092Mike LeBeau 747466741d8a78965b8509bf527344f289e50873092Mike LeBeau if (DEBUG) { 748466741d8a78965b8509bf527344f289e50873092Mike LeBeau Log.i(TAG, "onUpdateSelection: oss=" + oldSelStart 749466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", ose=" + oldSelEnd 750025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa + ", lss=" + mLastSelectionStart 751025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa + ", lse=" + mLastSelectionEnd 752466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", nss=" + newSelStart 753466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", nse=" + newSelEnd 754466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", cs=" + candidatesStart 755466741d8a78965b8509bf527344f289e50873092Mike LeBeau + ", ce=" + candidatesEnd); 756466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 757466741d8a78965b8509bf527344f289e50873092Mike LeBeau 758b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.setCursorAndSelection(newSelEnd, newSelStart); 7594f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 760923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // If the current selection in the text view changes, we should 761923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // clear whatever candidate text we have. 762025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa final boolean selectionChanged = (newSelStart != candidatesEnd 763025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa || newSelEnd != candidatesEnd) && mLastSelectionStart != newSelStart; 764025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa final boolean candidatesCleared = candidatesStart == -1 && candidatesEnd == -1; 765025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa if (((mComposing.length() > 0 && mHasValidSuggestions) 766b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok || mVoiceProxy.isVoiceInputHighlighted()) 767025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa && (selectionChanged || candidatesCleared)) { 768025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa if (candidatesCleared) { 769025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa // If the composing span has been cleared, save the typed word in the history for 770025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa // recorrection before we reset the candidate strip. Then, we'll be able to show 771025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa // suggestions for recorrection right away. 772025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa saveWordInHistory(mComposing); 773025a5e356ec74dbed7f805a2e43adbb2a35320f8Ken Wakasa } 774923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mComposing.setLength(0); 7759fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mHasValidSuggestions = false; 77689bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (isCursorTouchingWord()) { 777cb3320179d39a7983874697a0aa428b127675c9dJean Chalard mHandler.cancelUpdateBigramPredictions(); 77889bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard mHandler.postUpdateSuggestions(); 77989bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } else { 78089bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard setPunctuationSuggestions(); 78189bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 782923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.reset(); 783923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 784923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 785923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.finishComposingText(); 786923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 787b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.setVoiceInputHighlighted(false); 7889fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka } else if (!mHasValidSuggestions && !mJustAccepted) { 789662bb7c26cadd5026cb3d4e5d081aae163bd5a3aTadashi G. Takaoka if (TextEntryState.isAcceptedDefault() || TextEntryState.isSpaceAfterPicked()) { 790662bb7c26cadd5026cb3d4e5d081aae163bd5a3aTadashi G. Takaoka if (TextEntryState.isAcceptedDefault()) 791662bb7c26cadd5026cb3d4e5d081aae163bd5a3aTadashi G. Takaoka TextEntryState.reset(); 792e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mJustAddedAutoSpace = false; // The user moved the cursor. 7939a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 794923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 795923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mJustAccepted = false; 796d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateShiftKeyState(); 797466741d8a78965b8509bf527344f289e50873092Mike LeBeau 798979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Make a note of the cursor position 799979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mLastSelectionStart = newSelStart; 800979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mLastSelectionEnd = newSelEnd; 801466741d8a78965b8509bf527344f289e50873092Mike LeBeau 802952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa if (mRecorrectionEnabled && isShowingSuggestionsStrip()) { 80366b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok // Don't look for corrections if the keyboard is not visible 8041679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka if (mKeyboardSwitcher.isInputViewShown()) { 80566b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok // Check if we should go in or out of correction mode. 8066f99d12b0752ecdbceda7e5fddead214f939f533Tadashi G. Takaoka if (isSuggestionsRequested() 80766b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok && (candidatesStart == candidatesEnd || newSelStart != oldSelStart 808952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa || TextEntryState.isRecorrecting()) 8099fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka && (newSelStart < newSelEnd - 1 || !mHasValidSuggestions)) { 81066b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok if (isCursorTouchingWord() || mLastSelectionStart < mLastSelectionEnd) { 811cb3320179d39a7983874697a0aa428b127675c9dJean Chalard mHandler.cancelUpdateBigramPredictions(); 812d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateOldSuggestions(); 81366b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok } else { 814952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa abortRecorrection(false); 81589bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // If showing the "touch again to save" hint, do not replace it. Else, 81689bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // show the bigrams if we are at the end of the text, punctuation otherwise. 81789bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (mCandidateView != null 8187599cfea4a2d56f4779452ec8e8742f7b9629cc0satok && !mCandidateView.isShowingAddToDictionaryHint()) { 81989bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard InputConnection ic = getCurrentInputConnection(); 82089bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (null == ic || !TextUtils.isEmpty(ic.getTextAfterCursor(1, 0))) { 82189bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (!isShowingPunctuationList()) setPunctuationSuggestions(); 82289bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } else { 823cb3320179d39a7983874697a0aa428b127675c9dJean Chalard mHandler.postUpdateBigramPredictions(); 82489bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 82555b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa } 82666b42a1c2d38813be104a7f0435ec6e6ec1c6e65satok } 827b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 828466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 829466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 830923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 831923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 832c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani /** 833c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * This is called when the user has clicked on the extracted text view, 834c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * when running in fullscreen mode. The default implementation hides 835c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * the candidates view when this happens, but only if the extracted text 836c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * editor has a vertical scroll bar because its text doesn't fit. 837c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * Here we override the behavior due to the possibility that a re-correction could 838c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * cause the candidate strip to disappear and re-appear. 839c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani */ 840c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani @Override 841c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani public void onExtractedTextClicked() { 842952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa if (mRecorrectionEnabled && isSuggestionsRequested()) return; 843c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 844c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani super.onExtractedTextClicked(); 845c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani } 846c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 847c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani /** 848c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * This is called when the user has performed a cursor movement in the 849c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * extracted text view, when it is running in fullscreen mode. The default 850c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * implementation hides the candidates view when a vertical movement 851c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * happens, but only if the extracted text editor has a vertical scroll bar 852c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * because its text doesn't fit. 853c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * Here we override the behavior due to the possibility that a re-correction could 854c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * cause the candidate strip to disappear and re-appear. 855c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani */ 856c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani @Override 857c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani public void onExtractedCursorMovement(int dx, int dy) { 858952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa if (mRecorrectionEnabled && isSuggestionsRequested()) return; 859c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 860c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani super.onExtractedCursorMovement(dx, dy); 861c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani } 862c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 863923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 864923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void hideWindow() { 865979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.commit(); 8661b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mKeyboardSwitcher.onAutoCorrectionStateChanged(false); 867979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 868923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (TRACE) Debug.stopMethodTracing(); 8696e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani if (mOptionsDialog != null && mOptionsDialog.isShowing()) { 8706e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani mOptionsDialog.dismiss(); 8716e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani mOptionsDialog = null; 8726e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani } 873b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.hideVoiceWindow(mConfigurationChanging); 874979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mWordHistory.clear(); 875923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.hideWindow(); 876923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 877923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 878923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 8791b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka public void onDisplayCompletions(CompletionInfo[] applicationSpecifiedCompletions) { 880979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (DEBUG) { 881a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa Log.i(TAG, "Received completions:"); 882bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok if (applicationSpecifiedCompletions != null) { 883bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok for (int i = 0; i < applicationSpecifiedCompletions.length; i++) { 884bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok Log.i(TAG, " #" + i + ": " + applicationSpecifiedCompletions[i]); 885bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok } 886923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 887923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 8881b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka if (mApplicationSpecifiedCompletionOn) { 8891b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mApplicationSpecifiedCompletions = applicationSpecifiedCompletions; 8901b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka if (applicationSpecifiedCompletions == null) { 891b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani clearSuggestions(); 892923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 893923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 894a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 8957e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords.Builder builder = new SuggestedWords.Builder() 8961b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka .setApplicationSpecifiedCompletions(applicationSpecifiedCompletions) 8977e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka .setTypedWordValid(true) 8987e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka .setHasMinimalSuggestion(true); 899979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // When in fullscreen mode, show completions generated by the application 9007e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka setSuggestions(builder.build()); 901923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mBestWord = null; 902543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa setCandidatesViewShown(true); 903923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 904923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 905923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 906543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa private void setCandidatesViewShownInternal(boolean shown, boolean needsInputViewShown) { 9077a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka // TODO: Modify this if we support candidates with hard keyboard 908923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (onEvaluateInputViewShown()) { 9097a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka final boolean shouldShowCandidates = shown 9107a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true); 9117a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka if (isExtractViewShown()) { 9127a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka // No need to have extra space to show the key preview. 9137a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka mCandidateViewContainer.setMinimumHeight(0); 9147a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka super.setCandidatesViewShown(shown); 9157a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka } else { 9167a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka // We must control the visibility of the suggestion strip in order to avoid clipped 9177a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka // key previews, even when we don't show the suggestion strip. 9187a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka mCandidateViewContainer.setVisibility( 9197a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka shouldShowCandidates ? View.VISIBLE : View.INVISIBLE); 9207a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka super.setCandidatesViewShown(true); 9217a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka } 922923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 923923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 924a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 925923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 926543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa public void setCandidatesViewShown(boolean shown) { 927543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa setCandidatesViewShownInternal(shown, true /* needsInputViewShown */ ); 928543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa } 929543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa 930543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa @Override 931923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onComputeInsets(InputMethodService.Insets outInsets) { 932923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onComputeInsets(outInsets); 9337a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka final KeyboardView inputView = mKeyboardSwitcher.getInputView(); 93446ca84584810dfe606e709b3fe283cbde8aba5f5Tadashi G. Takaoka if (inputView == null) 93546ca84584810dfe606e709b3fe283cbde8aba5f5Tadashi G. Takaoka return; 93646ca84584810dfe606e709b3fe283cbde8aba5f5Tadashi G. Takaoka final int containerHeight = mCandidateViewContainer.getHeight(); 93746ca84584810dfe606e709b3fe283cbde8aba5f5Tadashi G. Takaoka int touchY = containerHeight; 9389e347d3d448e48229c46aad394ec9bd60cd5807bsatok // Need to set touchable region only if input view is being shown 93946ca84584810dfe606e709b3fe283cbde8aba5f5Tadashi G. Takaoka if (mKeyboardSwitcher.isInputViewShown()) { 9407a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka if (mCandidateViewContainer.getVisibility() == View.VISIBLE) { 9417a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka touchY -= mCandidateStripHeight; 9429e347d3d448e48229c46aad394ec9bd60cd5807bsatok } 9437a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka final int touchWidth = inputView.getWidth(); 9447a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka final int touchHeight = inputView.getHeight() + containerHeight 9457a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka // Extend touchable region below the keyboard. 9467a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka + EXTENDED_TOUCHABLE_REGION_HEIGHT; 9479e347d3d448e48229c46aad394ec9bd60cd5807bsatok if (DEBUG) { 9487a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka Log.d(TAG, "Touchable region: y=" + touchY + " width=" + touchWidth 9497a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka + " height=" + touchHeight); 9509e347d3d448e48229c46aad394ec9bd60cd5807bsatok } 9517a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka setTouchableRegionCompat(outInsets, 0, touchY, touchWidth, touchHeight); 9529e347d3d448e48229c46aad394ec9bd60cd5807bsatok } 95346ca84584810dfe606e709b3fe283cbde8aba5f5Tadashi G. Takaoka outInsets.contentTopInsets = touchY; 95446ca84584810dfe606e709b3fe283cbde8aba5f5Tadashi G. Takaoka outInsets.visibleTopInsets = touchY; 955923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 956a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 957923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 958979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public boolean onEvaluateFullscreenMode() { 959458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa final Resources res = mResources; 960458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa DisplayMetrics dm = res.getDisplayMetrics(); 961979f8690967ff5409fe18f5085858ccdb8e0ccf1satok float displayHeight = dm.heightPixels; 962979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // If the display is more than X inches high, don't go to fullscreen mode 963458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa float dimen = res.getDimension(R.dimen.max_height_for_fullscreen); 964979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (displayHeight > dimen) { 965979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return false; 966979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } else { 967979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return super.onEvaluateFullscreenMode(); 968979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 969979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 970979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 971979f8690967ff5409fe18f5085858ccdb8e0ccf1satok @Override 972923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean onKeyDown(int keyCode, KeyEvent event) { 973923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (keyCode) { 974e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_BACK: 975e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (event.getRepeatCount() == 0 && mKeyboardSwitcher.getInputView() != null) { 976e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (mKeyboardSwitcher.getInputView().handleBack()) { 9776e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani return true; 9786e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani } 979e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } 980e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka break; 981923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 982923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return super.onKeyDown(keyCode, event); 983923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 984923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 985923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 986923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean onKeyUp(int keyCode, KeyEvent event) { 987923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (keyCode) { 988e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_DPAD_DOWN: 989e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_DPAD_UP: 990e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_DPAD_LEFT: 991e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka case KeyEvent.KEYCODE_DPAD_RIGHT: 992e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka // Enable shift key and DPAD to do selections 993e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (mKeyboardSwitcher.isInputViewShown() 994e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka && mKeyboardSwitcher.isShiftedOrShiftLocked()) { 995e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka KeyEvent newEvent = new KeyEvent(event.getDownTime(), event.getEventTime(), 996e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka event.getAction(), event.getKeyCode(), event.getRepeatCount(), 997e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka event.getDeviceId(), event.getScanCode(), 998e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON); 999e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka InputConnection ic = getCurrentInputConnection(); 1000e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (ic != null) 1001e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka ic.sendKeyEvent(newEvent); 1002e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka return true; 1003e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } 1004e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka break; 1005923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1006923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return super.onKeyUp(keyCode, event); 1007923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1008923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1009409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void commitTyped(InputConnection inputConnection) { 10109fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mHasValidSuggestions) { 10119fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mHasValidSuggestions = false; 1012923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mComposing.length() > 0) { 1013923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (inputConnection != null) { 1014923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project inputConnection.commitText(mComposing, 1); 1015923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1016923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCommittedLength = mComposing.length(); 1017923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.acceptedTyped(mComposing); 1018bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok addToAutoAndUserBigramDictionaries(mComposing, AutoDictionary.FREQUENCY_FOR_TYPED); 1019923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1020923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project updateSuggestions(); 1021923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1022923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1023923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1024b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka public boolean getCurrentAutoCapsState() { 1025923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 10261c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani EditorInfo ei = getCurrentInputEditorInfo(); 1027e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (mAutoCap && ic != null && ei != null && ei.inputType != InputType.TYPE_NULL) { 1028b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return ic.getCursorCapsMode(ei.inputType) != 0; 10291c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani } 1030b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka return false; 10311c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani } 10321c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani 1033923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void swapPunctuationAndSpace() { 1034923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final InputConnection ic = getCurrentInputConnection(); 1035923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic == null) return; 1036923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence lastTwo = ic.getTextBeforeCursor(2, 0); 1037923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (lastTwo != null && lastTwo.length() == 2 1038571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastTwo.charAt(0) == Keyboard.CODE_SPACE 1039571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && isSentenceSeparator(lastTwo.charAt(1))) { 1040923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.beginBatchEdit(); 1041923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.deleteSurroundingText(2, 0); 1042923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.commitText(lastTwo.charAt(1) + " ", 1); 1043923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.endBatchEdit(); 1044b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 10459a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = true; 1046923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1047923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 10481c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani 10494ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa private void reswapPeriodAndSpace() { 10504ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa final InputConnection ic = getCurrentInputConnection(); 10514ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa if (ic == null) return; 10524ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa CharSequence lastThree = ic.getTextBeforeCursor(3, 0); 10534ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa if (lastThree != null && lastThree.length() == 3 1054571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastThree.charAt(0) == Keyboard.CODE_PERIOD 1055571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastThree.charAt(1) == Keyboard.CODE_SPACE 1056571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastThree.charAt(2) == Keyboard.CODE_PERIOD) { 10574ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa ic.beginBatchEdit(); 10584ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa ic.deleteSurroundingText(3, 0); 10594ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa ic.commitText(" ..", 1); 10604ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa ic.endBatchEdit(); 1061b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 10624ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa } 10634ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa } 10644ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa 1065923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void doubleSpace() { 1066923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mCorrectionMode == Suggest.CORRECTION_NONE) return; 1067923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final InputConnection ic = getCurrentInputConnection(); 1068923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic == null) return; 1069923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence lastThree = ic.getTextBeforeCursor(3, 0); 1070923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (lastThree != null && lastThree.length() == 3 1071923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project && Character.isLetterOrDigit(lastThree.charAt(0)) 1072571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastThree.charAt(1) == Keyboard.CODE_SPACE 1073fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka && lastThree.charAt(2) == Keyboard.CODE_SPACE 1074fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka && mHandler.isAcceptingDoubleSpaces()) { 1075fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka mHandler.cancelDoubleSpacesTimer(); 1076923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.beginBatchEdit(); 1077923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.deleteSurroundingText(2, 0); 1078923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.commitText(". ", 1); 1079923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.endBatchEdit(); 1080b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 10819a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = true; 1082fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka } else { 1083fc20f2198d6703d65eab22f40f9b8aa2c8e3a0eaTadashi G. Takaoka mHandler.startDoubleSpacesTimer(); 1084923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1085923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1086a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 108741a519729505a877844f2c57a33509c302dddbceKen Wakasa private void maybeRemovePreviousPeriod(CharSequence text) { 108841a519729505a877844f2c57a33509c302dddbceKen Wakasa final InputConnection ic = getCurrentInputConnection(); 108941a519729505a877844f2c57a33509c302dddbceKen Wakasa if (ic == null) return; 109041a519729505a877844f2c57a33509c302dddbceKen Wakasa 109141a519729505a877844f2c57a33509c302dddbceKen Wakasa // When the text's first character is '.', remove the previous period 109241a519729505a877844f2c57a33509c302dddbceKen Wakasa // if there is one. 109341a519729505a877844f2c57a33509c302dddbceKen Wakasa CharSequence lastOne = ic.getTextBeforeCursor(1, 0); 10944ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa if (lastOne != null && lastOne.length() == 1 1095571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastOne.charAt(0) == Keyboard.CODE_PERIOD 1096571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && text.charAt(0) == Keyboard.CODE_PERIOD) { 109741a519729505a877844f2c57a33509c302dddbceKen Wakasa ic.deleteSurroundingText(1, 0); 109841a519729505a877844f2c57a33509c302dddbceKen Wakasa } 109941a519729505a877844f2c57a33509c302dddbceKen Wakasa } 110041a519729505a877844f2c57a33509c302dddbceKen Wakasa 11019a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa private void removeTrailingSpace() { 11029a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa final InputConnection ic = getCurrentInputConnection(); 11039a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic == null) return; 11049a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa 11059a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa CharSequence lastOne = ic.getTextBeforeCursor(1, 0); 11069a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (lastOne != null && lastOne.length() == 1 1107571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka && lastOne.charAt(0) == Keyboard.CODE_SPACE) { 11089a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.deleteSurroundingText(1, 0); 11099a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 11109a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 11119a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa 1112923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean addWordToDictionary(String word) { 1113923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mUserDictionary.addWord(word, 128); 11146558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // Suggestion strip should be updated after the operation of adding word to the 11156558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // user dictionary 1116d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 1117923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 1118923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1119923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1120923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean isAlphabet(int code) { 1121923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (Character.isLetter(code)) { 1122923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 1123923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1124923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return false; 1125923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1126923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1127a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1128e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka private void onSettingsKeyPressed() { 11299a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok if (!isShowingOptionDialog()) { 11302fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka if (!mConfigEnableShowSubtypeSettings) { 11312fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka showSubtypeSelectorAndSettings(); 11322fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } else if (Utils.hasMultipleEnabledIMEsOrSubtypes(mImm)) { 11339a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok showOptionsMenu(); 11349a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } else { 11359a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok launchSettings(); 11369a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 11379a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 11389a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 11399a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok 1140e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka private void onSettingsKeyLongPressed() { 11419a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok if (!isShowingOptionDialog()) { 11429502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka if (Utils.hasMultipleEnabledIMEsOrSubtypes(mImm)) { 114379efbed76f638be298493107fa2d0cd1b5eb529esatok mImm.showInputMethodPicker(); 11449a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } else { 11459a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok launchSettings(); 11469a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 11479a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 11489a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 11499a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok 11509a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok private boolean isShowingOptionDialog() { 11519a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok return mOptionsDialog != null && mOptionsDialog.isShowing(); 11529a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 11539a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok 11545f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka // Implementation of {@link KeyboardActionListener}. 11555a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 11568aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) { 1157923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project long when = SystemClock.uptimeMillis(); 1158571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (primaryCode != Keyboard.CODE_DELETE || when > mLastKeyTime + QUICK_PRESS) { 1159923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mDeleteCount = 0; 1160923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1161923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mLastKeyTime = when; 1162b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 1163dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette final boolean accessibilityEnabled = switcher.isAccessibilityEnabled(); 1164b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); 1165923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (primaryCode) { 1166571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_DELETE: 11674189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka handleBackspace(); 11684189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka mDeleteCount++; 11694189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka LatinImeLogger.logOnDelete(); 11704189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1171571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_SHIFT: 11724189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka // Shift key is handled in onPress() when device has distinct multi-touch panel. 1173dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette if (!distinctMultiTouch || accessibilityEnabled) 1174b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.toggleShift(); 11754189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1176e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka case Keyboard.CODE_SWITCH_ALPHA_SYMBOL: 11774189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka // Symbol key is handled in onPress() when device has distinct multi-touch panel. 1178dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette if (!distinctMultiTouch || accessibilityEnabled) 1179b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.changeKeyboardMode(); 11804189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1181571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_CANCEL: 11824189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka if (!isShowingOptionDialog()) { 11834189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka handleClose(); 11844189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka } 11854189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1186e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka case Keyboard.CODE_SETTINGS: 1187e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka onSettingsKeyPressed(); 11884189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1189e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka case Keyboard.CODE_SETTINGS_LONGPRESS: 1190e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka onSettingsKeyLongPressed(); 11914189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1192d2c5fdda862f6dd2a1e020cf674c35fbbc63fc92Tadashi G. Takaoka case LatinKeyboard.CODE_NEXT_LANGUAGE: 119388fc9d44186120f9edc5cf7ec0e2af85260fed04satok toggleLanguage(true); 11944189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1195d2c5fdda862f6dd2a1e020cf674c35fbbc63fc92Tadashi G. Takaoka case LatinKeyboard.CODE_PREV_LANGUAGE: 119688fc9d44186120f9edc5cf7ec0e2af85260fed04satok toggleLanguage(false); 11974189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1198571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_CAPSLOCK: 1199b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.toggleCapsLock(); 12004189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1201d2c5fdda862f6dd2a1e020cf674c35fbbc63fc92Tadashi G. Takaoka case Keyboard.CODE_SHORTCUT: 120220cdb37bd062ae6cb6d42ad6229a19733476cd55satok mSubtypeSwitcher.switchToShortcutIME(); 12034189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 1204571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_TAB: 120545911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka handleTab(); 12064189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka break; 12074189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka default: 1208571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (primaryCode != Keyboard.CODE_ENTER) { 12094189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka mJustAddedAutoSpace = false; 12104189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka } 12114189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka if (isWordSeparator(primaryCode)) { 1212b5d17e52fcda39d540822e615bfb7ed5074e0034satok handleSeparator(primaryCode, x, y); 12134189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka } else { 12148fbd55229243cb66c03d5ea1f79dfb39f596590dsatok handleCharacter(primaryCode, keyCodes, x, y); 12154189eb23082fcd4bf8cfb2085d18e226e0e7ce13Tadashi G. Takaoka } 1216923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1217b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.onKey(primaryCode); 1218dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani // Reset after any single keystroke 1219dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani mEnteredText = null; 1220923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1221a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 12225a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 12238aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka public void onTextInput(CharSequence text) { 1224b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.commitVoiceInput(); 1225923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 1226923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic == null) return; 1227952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa abortRecorrection(false); 1228923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.beginBatchEdit(); 122955b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka commitTyped(ic); 123041a519729505a877844f2c57a33509c302dddbceKen Wakasa maybeRemovePreviousPeriod(text); 1231923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.commitText(text, 1); 1232923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.endBatchEdit(); 1233b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 12345f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka mKeyboardSwitcher.onKey(Keyboard.CODE_DUMMY); 12359a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = false; 1236dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani mEnteredText = text; 1237923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1238923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 12395a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 12408aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka public void onCancelInput() { 124183e63ace2a1bd5b3c27d26d914456c2b0def17c5Tadashi G. Takaoka // User released a finger outside any key 12425f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka mKeyboardSwitcher.onCancelInput(); 124383e63ace2a1bd5b3c27d26d914456c2b0def17c5Tadashi G. Takaoka } 124483e63ace2a1bd5b3c27d26d914456c2b0def17c5Tadashi G. Takaoka 1245923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void handleBackspace() { 1246b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok if (mVoiceProxy.logAndRevertVoiceInput()) return; 12474f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1248504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka final InputConnection ic = getCurrentInputConnection(); 1249504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka if (ic == null) return; 1250979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ic.beginBatchEdit(); 1251979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1252b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.handleBackspace(); 12534f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1254504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka boolean deleteChar = false; 12559fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mHasValidSuggestions) { 1256923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int length = mComposing.length(); 1257923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (length > 0) { 1258923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mComposing.delete(length - 1, length); 1259923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mWord.deleteLast(); 1260923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.setComposingText(mComposing, 1); 1261923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mComposing.length() == 0) { 12629fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mHasValidSuggestions = false; 1263923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 126489bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (1 == length) { 126589bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // 1 == length means we are about to erase the last character of the word, 126689bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // so we can show bigrams. 1267cb3320179d39a7983874697a0aa428b127675c9dJean Chalard mHandler.postUpdateBigramPredictions(); 126889bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } else { 126989bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // length > 1, so we still have letters to deduce a suggestion from. 127089bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard mHandler.postUpdateSuggestions(); 127189bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 1272923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1273923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.deleteSurroundingText(1, 0); 1274923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1275923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1276923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project deleteChar = true; 1277923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1278d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateShiftKeyState(); 1279504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka 1280923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.backspace(); 1281662bb7c26cadd5026cb3d4e5d081aae163bd5a3aTadashi G. Takaoka if (TextEntryState.isUndoCommit()) { 1282923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project revertLastWord(deleteChar); 1283979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ic.endBatchEdit(); 1284923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1285504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka } 1286504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka 1287504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) { 1288dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani ic.deleteSurroundingText(mEnteredText.length(), 0); 1289923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else if (deleteChar) { 12906558253160e2039c87f424bd814f402ecd31de3bKen Wakasa if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) { 12916558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // Go back to the suggestion mode if the user canceled the 129255b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa // "Touch again to save". 12936558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // NOTE: In gerenal, we don't revert the word when backspacing 12946558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // from a manual suggestion pick. We deliberately chose a 12956558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // different behavior only in the case of picking the first 12966558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // suggestion (typed word). It's intentional to have made this 12976558253160e2039c87f424bd814f402ecd31de3bKen Wakasa // inconsistent with backspacing after selecting other suggestions. 12986558253160e2039c87f424bd814f402ecd31de3bKen Wakasa revertLastWord(deleteChar); 12996558253160e2039c87f424bd814f402ecd31de3bKen Wakasa } else { 1300923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); 13016558253160e2039c87f424bd814f402ecd31de3bKen Wakasa if (mDeleteCount > DELETE_ACCELERATE_AT) { 13026558253160e2039c87f424bd814f402ecd31de3bKen Wakasa sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); 13036558253160e2039c87f424bd814f402ecd31de3bKen Wakasa } 1304923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1305923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1306979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ic.endBatchEdit(); 1307923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1308923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 130945911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka private void handleTab() { 131045911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final int imeOptions = getCurrentInputEditorInfo().imeOptions; 1311b2707856aba4fc9b063f26305f1fb603b19c1701satok if (!EditorInfoCompatUtils.hasFlagNavigateNext(imeOptions) 1312b2707856aba4fc9b063f26305f1fb603b19c1701satok && !EditorInfoCompatUtils.hasFlagNavigatePrevious(imeOptions)) { 131345911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka sendDownUpKeyEvents(KeyEvent.KEYCODE_TAB); 131445911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka return; 131545911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka } 131645911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka 131745911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final InputConnection ic = getCurrentInputConnection(); 131845911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka if (ic == null) 131945911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka return; 132045911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka 132145911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka // True if keyboard is in either chording shift or manual temporary upper case mode. 132245911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final boolean isManualTemporaryUpperCase = mKeyboardSwitcher.isManualTemporaryUpperCase(); 1323b2707856aba4fc9b063f26305f1fb603b19c1701satok if (EditorInfoCompatUtils.hasFlagNavigateNext(imeOptions) 132445911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka && !isManualTemporaryUpperCase) { 1325b2707856aba4fc9b063f26305f1fb603b19c1701satok EditorInfoCompatUtils.performEditorActionNext(ic); 132645911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka ic.performEditorAction(EditorInfo.IME_ACTION_NEXT); 1327b2707856aba4fc9b063f26305f1fb603b19c1701satok } else if (EditorInfoCompatUtils.hasFlagNavigatePrevious(imeOptions) 132845911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka && isManualTemporaryUpperCase) { 1329b2707856aba4fc9b063f26305f1fb603b19c1701satok EditorInfoCompatUtils.performEditorActionPrevious(ic); 133045911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka } 133145911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka } 133245911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka 1333952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa private void abortRecorrection(boolean force) { 1334952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa if (force || TextEntryState.isRecorrecting()) { 1335952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa TextEntryState.onAbortRecorrection(); 1336ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setCandidatesViewShown(isCandidateStripVisible()); 1337979f8690967ff5409fe18f5085858ccdb8e0ccf1satok getCurrentInputConnection().finishComposingText(); 1338b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani clearSuggestions(); 1339923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1340923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1341a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 13428fbd55229243cb66c03d5ea1f79dfb39f596590dsatok private void handleCharacter(int primaryCode, int[] keyCodes, int x, int y) { 1343b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.handleCharacter(); 13444f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1345952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa if (mLastSelectionStart == mLastSelectionEnd && TextEntryState.isRecorrecting()) { 1346952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa abortRecorrection(false); 1347b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 13484f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1349e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka int code = primaryCode; 13509fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (isAlphabet(code) && isSuggestionsRequested() && !isCursorTouchingWord()) { 13519fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (!mHasValidSuggestions) { 13529fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mHasValidSuggestions = true; 1353923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mComposing.setLength(0); 1354979f8690967ff5409fe18f5085858ccdb8e0ccf1satok saveWordInHistory(mBestWord); 1355923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mWord.reset(); 13567e99a28dfcc14f5b19220442db972ca8d786b4feKen Wakasa clearSuggestions(); 1357923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1358923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 13591679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 1360f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (switcher.isShiftedOrShiftLocked()) { 1361eef539c3f2b60af74a3ce05ac68288e7f86709aeAmith Yamasani if (keyCodes == null || keyCodes[0] < Character.MIN_CODE_POINT 1362eef539c3f2b60af74a3ce05ac68288e7f86709aeAmith Yamasani || keyCodes[0] > Character.MAX_CODE_POINT) { 1363eef539c3f2b60af74a3ce05ac68288e7f86709aeAmith Yamasani return; 1364eef539c3f2b60af74a3ce05ac68288e7f86709aeAmith Yamasani } 1365e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka code = keyCodes[0]; 1366e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (switcher.isAlphabetMode() && Character.isLowerCase(code)) { 1367e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka int upperCaseCode = Character.toUpperCase(code); 1368e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (upperCaseCode != code) { 1369e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka code = upperCaseCode; 137012a4e08a6440c95f29dc04efe83515a4ed045487Tadashi G. Takaoka } else { 137112a4e08a6440c95f29dc04efe83515a4ed045487Tadashi G. Takaoka // Some keys, such as [eszett], have upper case as multi-characters. 1372e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka String upperCase = new String(new int[] {code}, 0, 1).toUpperCase(); 13738aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka onTextInput(upperCase); 137412a4e08a6440c95f29dc04efe83515a4ed045487Tadashi G. Takaoka return; 137512a4e08a6440c95f29dc04efe83515a4ed045487Tadashi G. Takaoka } 1376979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1377923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 13789fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mHasValidSuggestions) { 1379f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka if (mComposing.length() == 0 && switcher.isAlphabetMode() 1380f27364600c742509b48857e6b8f17312033e0dc7Tadashi G. Takaoka && switcher.isShiftedOrShiftLocked()) { 13810b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa mWord.setFirstCharCapitalized(true); 1382923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1383e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mComposing.append((char) code); 13848fbd55229243cb66c03d5ea1f79dfb39f596590dsatok mWord.add(code, keyCodes, x, y); 1385923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 1386923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 13871c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani // If it's the first letter, make note of auto-caps state 13881c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani if (mWord.size() == 1) { 1389b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mWord.setAutoCapitalized(getCurrentAutoCapsState()); 13901c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani } 1391923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.setComposingText(mComposing, 1); 1392923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1393d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 1394923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1395e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka sendKeyChar((char)code); 1396923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1397b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka switcher.updateShiftState(); 1398979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (LatinIME.PERF_DEBUG) measureCps(); 1399b5d17e52fcda39d540822e615bfb7ed5074e0034satok TextEntryState.typedCharacter((char) code, isWordSeparator(code), x, y); 1400923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1401923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1402b5d17e52fcda39d540822e615bfb7ed5074e0034satok private void handleSeparator(int primaryCode, int x, int y) { 1403b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.handleSeparator(); 14044f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 140555b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa // Should dismiss the "Touch again to save" message when handling separator 14066558253160e2039c87f424bd814f402ecd31de3bKen Wakasa if (mCandidateView != null && mCandidateView.dismissAddToDictionaryHint()) { 1407cb3320179d39a7983874697a0aa428b127675c9dJean Chalard mHandler.cancelUpdateBigramPredictions(); 1408d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 14096558253160e2039c87f424bd814f402ecd31de3bKen Wakasa } 14106558253160e2039c87f424bd814f402ecd31de3bKen Wakasa 1411923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project boolean pickedDefault = false; 1412923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Handle separator 14131b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final InputConnection ic = getCurrentInputConnection(); 1414923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 1415923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.beginBatchEdit(); 1416952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa abortRecorrection(false); 1417923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 14189fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mHasValidSuggestions) { 1419923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // In certain languages where single quote is a separator, it's better 1420a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker // not to auto correct, but accept the typed word. For instance, 1421923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // in Italian dov' should not be expanded to dove' because the elision 1422923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // requires the last vowel to be removed. 14236f99d12b0752ecdbceda7e5fddead214f939f533Tadashi G. Takaoka if (mAutoCorrectOn && primaryCode != '\'') { 1424b5d17e52fcda39d540822e615bfb7ed5074e0034satok pickedDefault = pickDefaultSuggestion(primaryCode); 14259a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa // Picked the suggestion by the space key. We consider this 14269a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa // as "added an auto space". 1427571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (primaryCode == Keyboard.CODE_SPACE) { 14289a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = true; 14299a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 1430923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1431923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project commitTyped(ic); 1432923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1433923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1434571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (mJustAddedAutoSpace && primaryCode == Keyboard.CODE_ENTER) { 14359a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa removeTrailingSpace(); 14369a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = false; 14379a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 1438923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sendKeyChar((char)primaryCode); 14394ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa 14404ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa // Handle the case of ". ." -> " .." with auto-space if necessary 14414ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa // before changing the TextEntryState. 1442662bb7c26cadd5026cb3d4e5d081aae163bd5a3aTadashi G. Takaoka if (TextEntryState.isPunctuationAfterAccepted() && primaryCode == Keyboard.CODE_PERIOD) { 14434ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa reswapPeriodAndSpace(); 14444ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa } 14454ca6d9dc09cf7635c9283e42f155957021b9f9acKen Wakasa 1446b5d17e52fcda39d540822e615bfb7ed5074e0034satok TextEntryState.typedCharacter((char) primaryCode, true, x, y); 144789bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard 1448662bb7c26cadd5026cb3d4e5d081aae163bd5a3aTadashi G. Takaoka if (TextEntryState.isPunctuationAfterAccepted() && primaryCode != Keyboard.CODE_ENTER) { 1449923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project swapPunctuationAndSpace(); 14509fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka } else if (isSuggestionsRequested() && primaryCode == Keyboard.CODE_SPACE) { 1451923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project doubleSpace(); 1452923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1453979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (pickedDefault) { 145455b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka CharSequence typedWord = mWord.getTypedWord(); 145555b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka TextEntryState.backToAcceptedDefault(typedWord); 145655b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka if (!TextUtils.isEmpty(typedWord) && !typedWord.equals(mBestWord)) { 1457b2707856aba4fc9b063f26305f1fb603b19c1701satok InputConnectionCompatUtils.commitCorrection( 145889bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard ic, mLastSelectionEnd - typedWord.length(), typedWord, mBestWord); 145955b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka if (mCandidateView != null) 146055b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka mCandidateView.onAutoCorrectionInverted(mBestWord); 146155b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka } 146289bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 146389bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (Keyboard.CODE_SPACE == primaryCode) { 146489bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (!isCursorTouchingWord()) { 146589bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard mHandler.cancelUpdateSuggestions(); 146689bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard mHandler.cancelUpdateOldSuggestions(); 1467cb3320179d39a7983874697a0aa428b127675c9dJean Chalard mHandler.postUpdateBigramPredictions(); 146889bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 146989bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } else { 147089bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // Set punctuation right away. onUpdateSelection will fire but tests whether it is 147189bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // already displayed or not, so it's okay. 147255b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka setPunctuationSuggestions(); 1473923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1474b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 1475923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 1476923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.endBatchEdit(); 1477923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1478923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1479466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1480923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void handleClose() { 1481923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project commitTyped(getCurrentInputConnection()); 1482b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.handleClose(); 1483923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project requestHideSelf(0); 14841679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); 14851679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka if (inputView != null) 14861679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka inputView.closing(); 1487923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1488923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1489979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void saveWordInHistory(CharSequence result) { 1490979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mWord.size() <= 1) { 1491979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return; 1492923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1493979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Skip if result is null. It happens in some edge case. 1494979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (TextUtils.isEmpty(result)) { 1495979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return; 1496923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1497979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1498979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Make a copy of the CharSequence, since it is/could be a mutable CharSequence 1499979f8690967ff5409fe18f5085858ccdb8e0ccf1satok final String resultCopy = result.toString(); 1500071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka WordAlternatives entry = new WordAlternatives(resultCopy, 1501979f8690967ff5409fe18f5085858ccdb8e0ccf1satok new WordComposer(mWord)); 1502979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mWordHistory.add(entry); 1503923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1504923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 15059fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka private boolean isSuggestionsRequested() { 1506c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka return mIsSettingsSuggestionStripOn 1507c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka && (mCorrectionMode > 0 || isShowingSuggestionsStrip()); 1508923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1509a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 15107599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private boolean isShowingPunctuationList() { 15117e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka return mSuggestPuncList == mCandidateView.getSuggestions(); 15127599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 15137599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 15149fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka private boolean isShowingSuggestionsStrip() { 15157599cfea4a2d56f4779452ec8e8742f7b9629cc0satok return (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_VALUE) 15167599cfea4a2d56f4779452ec8e8742f7b9629cc0satok || (mSuggestionVisibility == SUGGESTION_VISIBILILTY_SHOW_ONLY_PORTRAIT_VALUE 15177599cfea4a2d56f4779452ec8e8742f7b9629cc0satok && mOrientation == Configuration.ORIENTATION_PORTRAIT); 15187599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 15197599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 1520923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean isCandidateStripVisible() { 1521b5e00d5841b946de8970875231456228ae0eb6b1Ken Wakasa if (mCandidateView == null) 1522b5e00d5841b946de8970875231456228ae0eb6b1Ken Wakasa return false; 1523952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa if (mCandidateView.isShowingAddToDictionaryHint() || TextEntryState.isRecorrecting()) 15249fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return true; 15259fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (!isShowingSuggestionsStrip()) 15269fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return false; 15279fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (mApplicationSpecifiedCompletionOn) 15289fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return true; 15299fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return isSuggestionsRequested(); 1530923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1531923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1532409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void switchToKeyboardView() { 1533060efb6d82af1f896d90cb845c8ae07c726f85e1satok if (DEBUG) { 1534060efb6d82af1f896d90cb845c8ae07c726f85e1satok Log.d(TAG, "Switch to keyboard view."); 1535060efb6d82af1f896d90cb845c8ae07c726f85e1satok } 1536060efb6d82af1f896d90cb845c8ae07c726f85e1satok View v = mKeyboardSwitcher.getInputView(); 1537060efb6d82af1f896d90cb845c8ae07c726f85e1satok if (v != null) { 1538060efb6d82af1f896d90cb845c8ae07c726f85e1satok // Confirms that the keyboard view doesn't have parent view. 1539060efb6d82af1f896d90cb845c8ae07c726f85e1satok ViewParent p = v.getParent(); 1540060efb6d82af1f896d90cb845c8ae07c726f85e1satok if (p != null && p instanceof ViewGroup) { 1541060efb6d82af1f896d90cb845c8ae07c726f85e1satok ((ViewGroup) p).removeView(v); 15425a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka } 1543060efb6d82af1f896d90cb845c8ae07c726f85e1satok setInputView(v); 1544060efb6d82af1f896d90cb845c8ae07c726f85e1satok } 1545060efb6d82af1f896d90cb845c8ae07c726f85e1satok setCandidatesViewShown(isCandidateStripVisible()); 1546060efb6d82af1f896d90cb845c8ae07c726f85e1satok updateInputViewShown(); 1547060efb6d82af1f896d90cb845c8ae07c726f85e1satok mHandler.postUpdateSuggestions(); 1548466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1549466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1550409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void clearSuggestions() { 15517e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka setSuggestions(SuggestedWords.EMPTY); 1552466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1553466741d8a78965b8509bf527344f289e50873092Mike LeBeau 15547e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka public void setSuggestions(SuggestedWords words) { 1555b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok if (mVoiceProxy.getAndResetIsShowingHint()) { 1556466741d8a78965b8509bf527344f289e50873092Mike LeBeau setCandidatesView(mCandidateViewContainer); 1557466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1558466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1559466741d8a78965b8509bf527344f289e50873092Mike LeBeau if (mCandidateView != null) { 15607e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka mCandidateView.setSuggestions(words); 15619ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka if (mCandidateView.isConfigCandidateHighlightFontColorEnabled()) { 15629ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka mKeyboardSwitcher.onAutoCorrectionStateChanged( 15639ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka words.hasWordAboveAutoCorrectionScoreThreshold()); 15649ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka } 1565466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1566466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1567466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1568409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void updateSuggestions() { 1569923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Check if we have a suggestion engine attached. 15709fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if ((mSuggest == null || !isSuggestionsRequested()) 1571b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok && !mVoiceProxy.isVoiceInputHighlighted()) { 1572923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1573923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1574466741d8a78965b8509bf527344f289e50873092Mike LeBeau 15759fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (!mHasValidSuggestions) { 1576ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setPunctuationSuggestions(); 1577923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1578923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1579979f8690967ff5409fe18f5085858ccdb8e0ccf1satok showSuggestions(mWord); 1580979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1581979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 15827e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka private SuggestedWords.Builder getTypedSuggestions(WordComposer word) { 15839ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka return mSuggest.getSuggestedWordBuilder(mKeyboardSwitcher.getInputView(), word, null); 1584979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1585979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1586979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void showCorrections(WordAlternatives alternatives) { 15877e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords.Builder builder = alternatives.getAlternatives(); 15887e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka builder.setTypedWordValid(false).setHasMinimalSuggestion(false); 15897e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka showSuggestions(builder.build(), alternatives.getOriginalWord()); 1590979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1591979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1592979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void showSuggestions(WordComposer word) { 15939f67e12a0e3f77985fb8bafe0db4c00e32317b9asatok // TODO: May need a better way of retrieving previous word 1594e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(), 1595979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mWordSeparators); 15967e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder( 15979ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka mKeyboardSwitcher.getInputView(), word, prevWord); 1598923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 15996f99d12b0752ecdbceda7e5fddead214f939f533Tadashi G. Takaoka boolean correctionAvailable = !mInputTypeNoAutoCorrect && mSuggest.hasAutoCorrection(); 1600a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa final CharSequence typedWord = word.getTypedWord(); 1601bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok // Here, we want to promote a whitelisted word if exists. 1602bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok final boolean typedWordValid = AutoCorrection.isValidWordForAutoCorrection( 1603bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok mSuggest.getUnigramDictionaries(), typedWord, preferCapitalization()); 1604979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mCorrectionMode == Suggest.CORRECTION_FULL 1605979f8690967ff5409fe18f5085858ccdb8e0ccf1satok || mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM) { 1606923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project correctionAvailable |= typedWordValid; 1607923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 16084a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani // Don't auto-correct words with multiple capital letter 1609979f8690967ff5409fe18f5085858ccdb8e0ccf1satok correctionAvailable &= !word.isMostlyCaps(); 1610952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa correctionAvailable &= !TextEntryState.isRecorrecting(); 1611979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1612a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa // Basically, we update the suggestion strip only when suggestion count > 1. However, 1613a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa // there is an exception: We update the suggestion strip whenever typed word's length 1614f3df63a93a8f623e2aca5895ee749bd297b58d12Tadashi G. Takaoka // is 1 or typed word is found in dictionary, regardless of suggestion count. Actually, 1615f3df63a93a8f623e2aca5895ee749bd297b58d12Tadashi G. Takaoka // in most cases, suggestion count is 1 when typed word's length is 1, but we do always 1616f3df63a93a8f623e2aca5895ee749bd297b58d12Tadashi G. Takaoka // need to clear the previous state when the user starts typing a word (i.e. typed word's 1617f3df63a93a8f623e2aca5895ee749bd297b58d12Tadashi G. Takaoka // length == 1). 1618f3df63a93a8f623e2aca5895ee749bd297b58d12Tadashi G. Takaoka if (builder.size() > 1 || typedWord.length() == 1 || typedWordValid 1619a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa || mCandidateView.isShowingAddToDictionaryHint()) { 16209fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka builder.setTypedWordValid(typedWordValid).setHasMinimalSuggestion(correctionAvailable); 16219fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka } else { 16229fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka final SuggestedWords previousSuggestions = mCandidateView.getSuggestions(); 16239fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (previousSuggestions == mSuggestPuncList) 16249fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka return; 16259fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka builder.addTypedWordAndPreviousSuggestions(typedWord, previousSuggestions); 16269fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka } 16277e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka showSuggestions(builder.build(), typedWord); 1628979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 16294a7ff90d513f8b6cbf39688c08be0828a57e311bAmith Yamasani 16307e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka private void showSuggestions(SuggestedWords suggestedWords, CharSequence typedWord) { 16317e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka setSuggestions(suggestedWords); 16327e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka if (suggestedWords.size() > 0) { 163314e427d5bb13d59d23fb317ef90a6c44ae279425satok if (Utils.shouldBlockedBySafetyNetForAutoCorrection(suggestedWords, mSuggest)) { 163482411d47ba7e8133ed2390c6920945e139a738cesatok mBestWord = typedWord; 163582411d47ba7e8133ed2390c6920945e139a738cesatok } else if (suggestedWords.hasAutoCorrectionWord()) { 16367e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka mBestWord = suggestedWords.getWord(1); 1637923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1638923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mBestWord = typedWord; 1639923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1640923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1641923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mBestWord = null; 1642923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1643ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setCandidatesViewShown(isCandidateStripVisible()); 1644923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1645923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1646b5d17e52fcda39d540822e615bfb7ed5074e0034satok private boolean pickDefaultSuggestion(int separatorCode) { 1647923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Complete any pending candidate query first 1648d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka if (mHandler.hasPendingUpdateSuggestions()) { 1649d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.cancelUpdateSuggestions(); 1650923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project updateSuggestions(); 1651923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 16526780b898ec2647a21319601a03ae1c393c0e1b29Amith Yamasani if (mBestWord != null && mBestWord.length() > 0) { 1653b5d17e52fcda39d540822e615bfb7ed5074e0034satok TextEntryState.acceptedDefault(mWord.getTypedWord(), mBestWord, separatorCode); 1654923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mJustAccepted = true; 165555b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka pickSuggestion(mBestWord); 16569468335a06d2b0e3ef15f4f57f8c1b0857b34ebeAmith Yamasani // Add the word to the auto dictionary if it's not a known word 1657bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok addToAutoAndUserBigramDictionaries(mBestWord, AutoDictionary.FREQUENCY_FOR_TYPED); 1658979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return true; 1659979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1660923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1661979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return false; 1662923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1663923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1664923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void pickSuggestionManually(int index, CharSequence suggestion) { 16657e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords suggestions = mCandidateView.getSuggestions(); 1666b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.flushAndLogAllTextModificationCounters(index, suggestion, mWordSeparators); 16674f1f2201bdd0e63a19e686caa3d17b16eb134f5eMaryam Garrett 1668952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa final boolean recorrecting = TextEntryState.isRecorrecting(); 16699a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa InputConnection ic = getCurrentInputConnection(); 16709a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic != null) { 16719a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.beginBatchEdit(); 16729a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 16731b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka if (mApplicationSpecifiedCompletionOn && mApplicationSpecifiedCompletions != null 16741b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka && index >= 0 && index < mApplicationSpecifiedCompletions.length) { 16751b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka CompletionInfo ci = mApplicationSpecifiedCompletions[index]; 1676923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 1677923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.commitCompletion(ci); 1678923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1679923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCommittedLength = suggestion.length(); 1680923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mCandidateView != null) { 1681923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCandidateView.clear(); 1682923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1683b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 16849a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic != null) { 16859a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.endBatchEdit(); 16869a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 1687923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 1688923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 16896a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani 16906a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani // If this is a punctuation, apply it through the normal key press 1691979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (suggestion.length() == 1 && (isWordSeparator(suggestion.charAt(0)) 1692979f8690967ff5409fe18f5085858ccdb8e0ccf1satok || isSuggestedPunctuation(suggestion.charAt(0)))) { 1693979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // Word separators are suggested before the user inputs something. 1694979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // So, LatinImeLogger logs "" as a user's input. 1695979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.logOnManualSuggestion( 16967e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka "", suggestion.toString(), index, suggestions.mWords); 169755b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa final char primaryCode = suggestion.charAt(0); 1698a96574fdd5e38a237a35b21a2b7c20a29138c648Tadashi G. Takaoka onCodeInput(primaryCode, new int[] { primaryCode }, 1699a96574fdd5e38a237a35b21a2b7c20a29138c648Tadashi G. Takaoka KeyboardActionListener.NOT_A_TOUCH_COORDINATE, 1700a96574fdd5e38a237a35b21a2b7c20a29138c648Tadashi G. Takaoka KeyboardActionListener.NOT_A_TOUCH_COORDINATE); 17019a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic != null) { 17029a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.endBatchEdit(); 17039a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 17046a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani return; 17056a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 170689bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (!mHasValidSuggestions) { 170789bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // If we are not composing a word, then it was a suggestion inferred from 170889bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // context - no user input. We should reset the word composer. 170989bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard mWord.reset(); 171089bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 17119a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAccepted = true; 171255b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka pickSuggestion(suggestion); 17139468335a06d2b0e3ef15f4f57f8c1b0857b34ebeAmith Yamasani // Add the word to the auto dictionary if it's not a known word 17140c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani if (index == 0) { 1715bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok addToAutoAndUserBigramDictionaries(suggestion, AutoDictionary.FREQUENCY_FOR_PICKED); 1716979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } else { 1717bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok addToOnlyBigramDictionary(suggestion, 1); 17180c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani } 1719979f8690967ff5409fe18f5085858ccdb8e0ccf1satok LatinImeLogger.logOnManualSuggestion(mComposing.toString(), suggestion.toString(), 17207e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka index, suggestions.mWords); 1721923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project TextEntryState.acceptedSuggestion(mComposing.toString(), suggestion); 1722923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Follow it with a space 1723952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa if (mAutoSpace && !recorrecting) { 1724923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sendSpace(); 17259a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa mJustAddedAutoSpace = true; 1726923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1727979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 17287f2ba16aa2adba95e0575a2c6d58f6240154f313Jean Chalard // We should show the hint if the user pressed the first entry AND either: 17297f2ba16aa2adba95e0575a2c6d58f6240154f313Jean Chalard // - There is no dictionary (we know that because we tried to load it => null != mSuggest 17307f2ba16aa2adba95e0575a2c6d58f6240154f313Jean Chalard // AND mHasDictionary is false) 17317f2ba16aa2adba95e0575a2c6d58f6240154f313Jean Chalard // - There is a dictionary and the word is not in it 17327f2ba16aa2adba95e0575a2c6d58f6240154f313Jean Chalard // Please note that if mSuggest is null, it means that everything is off: suggestion 17337f2ba16aa2adba95e0575a2c6d58f6240154f313Jean Chalard // and correction, so we shouldn't try to show the hint 17347f2ba16aa2adba95e0575a2c6d58f6240154f313Jean Chalard // We used to look at mCorrectionMode here, but showing the hint should have nothing 17357f2ba16aa2adba95e0575a2c6d58f6240154f313Jean Chalard // to do with the autocorrection setting. 1736bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok final boolean showingAddToDictionaryHint = index == 0 && mSuggest != null 1737bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok // If there is no dictionary the hint should be shown. 1738bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok && (!mHasDictionary 1739bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok // If "suggestion" is not in the dictionary, the hint should be shown. 1740bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok || !AutoCorrection.isValidWord( 1741bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok mSuggest.getUnigramDictionaries(), suggestion, true)); 1742b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani 1743952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa if (!recorrecting) { 1744b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // Fool the state watcher so that a subsequent backspace will not do a revert, unless 1745b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // we just did a correction, in which case we need to stay in 1746b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // TextEntryState.State.PICKED_SUGGESTION state. 1747b5d17e52fcda39d540822e615bfb7ed5074e0034satok TextEntryState.typedCharacter((char) Keyboard.CODE_SPACE, true, 1748b5d17e52fcda39d540822e615bfb7ed5074e0034satok WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE); 174989bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // From there on onUpdateSelection() will fire so suggestions will be updated 1750b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } else if (!showingAddToDictionaryHint) { 1751364da8c618303a7764595d2c15ee034a7671365dKen Wakasa // If we're not showing the "Touch again to save", then show corrections again. 1752979f8690967ff5409fe18f5085858ccdb8e0ccf1satok // In case the cursor position doesn't change, make sure we show the suggestions again. 1753b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani clearSuggestions(); 1754d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateOldSuggestions(); 1755979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1756b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (showingAddToDictionaryHint) { 175766a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani mCandidateView.showAddToDictionaryHint(suggestion); 175866a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani } 17599a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa if (ic != null) { 17609a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa ic.endBatchEdit(); 17619a503e07d594ddf3cd0c31609c5311440b975906Ken Wakasa } 1762923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1763a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1764979f8690967ff5409fe18f5085858ccdb8e0ccf1satok /** 1765979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * Commits the chosen word to the text field and saves it for later 1766979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * retrieval. 1767979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * @param suggestion the suggestion picked by the user to be committed to 1768979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * the text field 1769979f8690967ff5409fe18f5085858ccdb8e0ccf1satok */ 177055b9d333c5d260cb5da3f6a2d872bda8c03478d7Tadashi G. Takaoka private void pickSuggestion(CharSequence suggestion) { 1771b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 1772b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka if (!switcher.isKeyboardAvailable()) 17731679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka return; 1774923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 1775923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic != null) { 1776b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.rememberReplacedWord(suggestion, mWordSeparators); 1777979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ic.commitText(suggestion, 1); 1778923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1779979f8690967ff5409fe18f5085858ccdb8e0ccf1satok saveWordInHistory(suggestion); 17809fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka mHasValidSuggestions = false; 1781923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCommittedLength = suggestion.length(); 1782923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1783923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1784b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani /** 1785b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani * Tries to apply any typed alternatives for the word if we have any cached alternatives, 1786b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani * otherwise tries to find new corrections and completions for the word. 1787b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani * @param touching The word that the cursor is touching, with position information 1788b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani * @return true if an alternative was found, false otherwise. 1789b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani */ 1790e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka private boolean applyTypedAlternatives(EditingUtils.SelectedWord touching) { 1791b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // If we didn't find a match, search for result in typed word history 1792b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani WordComposer foundWord = null; 1793b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani WordAlternatives alternatives = null; 1794bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok // Search old suggestions to suggest re-corrected suggestions. 1795b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani for (WordAlternatives entry : mWordHistory) { 1796e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (TextUtils.equals(entry.getChosenWord(), touching.mWord)) { 1797071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka foundWord = entry.mWordComposer; 1798b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani alternatives = entry; 1799b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani break; 1800b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1801b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1802bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok // If we didn't find a match, at least suggest corrections as re-corrected suggestions. 1803b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (foundWord == null 1804bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok && (AutoCorrection.isValidWord( 1805bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok mSuggest.getUnigramDictionaries(), touching.mWord, true))) { 1806b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani foundWord = new WordComposer(); 1807e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka for (int i = 0; i < touching.mWord.length(); i++) { 1808e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka foundWord.add(touching.mWord.charAt(i), new int[] { 1809e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka touching.mWord.charAt(i) 18108fbd55229243cb66c03d5ea1f79dfb39f596590dsatok }, WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE); 1811b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1812e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka foundWord.setFirstCharCapitalized(Character.isUpperCase(touching.mWord.charAt(0))); 1813b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1814b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // Found a match, show suggestions 1815b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (foundWord != null || alternatives != null) { 1816b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (alternatives == null) { 1817071f47140cec02197de5e163f45c77990b39457dTadashi G. Takaoka alternatives = new WordAlternatives(touching.mWord, foundWord); 1818b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1819b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani showCorrections(alternatives); 1820b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (foundWord != null) { 1821b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani mWord = new WordComposer(foundWord); 1822b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } else { 1823b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani mWord.reset(); 1824b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1825b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani return true; 1826b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1827b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani return false; 1828b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1829b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani 1830979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void setOldSuggestions() { 18316f18a1fbcccf9cf5ca937b08098601a4fafead29satok if (!InputConnectionCompatUtils.RECORRECTION_SUPPORTED) return; 1832b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.setShowingVoiceSuggestions(false); 1833b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani if (mCandidateView != null && mCandidateView.isShowingAddToDictionaryHint()) { 1834b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani return; 1835b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } 1836979f8690967ff5409fe18f5085858ccdb8e0ccf1satok InputConnection ic = getCurrentInputConnection(); 1837979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (ic == null) return; 18389fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (!mHasValidSuggestions) { 1839b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani // Extract the selected or touching text 1840e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka EditingUtils.SelectedWord touching = EditingUtils.getWordAtCursorOrSelection(ic, 1841b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani mLastSelectionStart, mLastSelectionEnd, mWordSeparators); 1842979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1843e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (touching != null && touching.mWord.length() > 1) { 1844b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani ic.beginBatchEdit(); 1845979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1846b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok if (!mVoiceProxy.applyVoiceAlternatives(touching) 1847409220583333bdf06290dd9fd42f91b5c0d1b11asatok && !applyTypedAlternatives(touching)) { 1848952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa abortRecorrection(true); 1849b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani } else { 1850952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa TextEntryState.selectedForRecorrection(); 18516f18a1fbcccf9cf5ca937b08098601a4fafead29satok InputConnectionCompatUtils.underlineWord(ic, touching); 1852979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1853b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani 1854b00a1d0c0adbdfc507676772201e979e539a2801Amith Yamasani ic.endBatchEdit(); 1855979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } else { 1856952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa abortRecorrection(true); 1857ca26f20fa4903de46e374babbfba8c8a1a5cac93satok setPunctuationSuggestions(); // Show the punctuation suggestions list 1858979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1859979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } else { 1860952cb7e973bbc4c09728cb5967505f84c80c8bd6Ken Wakasa abortRecorrection(true); 1861979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1862979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1863979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 186489bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard private static final WordComposer sEmptyWordComposer = new WordComposer(); 1865cb3320179d39a7983874697a0aa428b127675c9dJean Chalard private void updateBigramPredictions() { 186689bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (mSuggest == null || !isSuggestionsRequested()) 186789bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard return; 186889bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard 1869cb3320179d39a7983874697a0aa428b127675c9dJean Chalard if (!mBigramPredictionEnabled) { 1870cb3320179d39a7983874697a0aa428b127675c9dJean Chalard setPunctuationSuggestions(); 1871cb3320179d39a7983874697a0aa428b127675c9dJean Chalard return; 1872cb3320179d39a7983874697a0aa428b127675c9dJean Chalard } 1873cb3320179d39a7983874697a0aa428b127675c9dJean Chalard 187489bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard final CharSequence prevWord = EditingUtils.getThisWord(getCurrentInputConnection(), 187589bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard mWordSeparators); 187689bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard SuggestedWords.Builder builder = mSuggest.getSuggestedWordBuilder( 187789bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard mKeyboardSwitcher.getInputView(), sEmptyWordComposer, prevWord); 187889bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard 187989bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (builder.size() > 0) { 188089bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // Explicitly supply an empty typed word (the no-second-arg version of 188189bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard // showSuggestions will retrieve the word near the cursor, we don't want that here) 188289bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard showSuggestions(builder.build(), ""); 188389bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } else { 188489bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard if (!isShowingPunctuationList()) setPunctuationSuggestions(); 188589bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 188689bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard } 188789bd776cf68150202d774d62cc1c88664aea5e9fJean Chalard 1888ca26f20fa4903de46e374babbfba8c8a1a5cac93satok private void setPunctuationSuggestions() { 18897e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka setSuggestions(mSuggestPuncList); 18909fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka setCandidatesViewShown(isCandidateStripVisible()); 18916a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 18926a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani 1893bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok private void addToAutoAndUserBigramDictionaries(CharSequence suggestion, int frequencyDelta) { 1894979f8690967ff5409fe18f5085858ccdb8e0ccf1satok checkAddToDictionary(suggestion, frequencyDelta, false); 1895979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1896979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1897bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok private void addToOnlyBigramDictionary(CharSequence suggestion, int frequencyDelta) { 1898979f8690967ff5409fe18f5085858ccdb8e0ccf1satok checkAddToDictionary(suggestion, frequencyDelta, true); 1899979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1900979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1901979f8690967ff5409fe18f5085858ccdb8e0ccf1satok /** 1902979f8690967ff5409fe18f5085858ccdb8e0ccf1satok * Adds to the UserBigramDictionary and/or AutoDictionary 1903bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok * @param selectedANotTypedWord true if it should be added to bigram dictionary if possible 1904979f8690967ff5409fe18f5085858ccdb8e0ccf1satok */ 1905979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private void checkAddToDictionary(CharSequence suggestion, int frequencyDelta, 1906bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok boolean selectedANotTypedWord) { 1907979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (suggestion == null || suggestion.length() < 1) return; 1908bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok 19090c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani // Only auto-add to dictionary if auto-correct is ON. Otherwise we'll be 19100c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani // adding words in situations where the user or application really didn't 19110c05902e331b03426754a1cfffe28d185dd8338cAmith Yamasani // want corrections enabled or learned. 1912979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (!(mCorrectionMode == Suggest.CORRECTION_FULL 1913979f8690967ff5409fe18f5085858ccdb8e0ccf1satok || mCorrectionMode == Suggest.CORRECTION_FULL_BIGRAM)) { 1914979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return; 1915979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1916bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok 1917bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok final boolean selectedATypedWordAndItsInAutoDic = 1918bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok !selectedANotTypedWord && mAutoDictionary.isValidWord(suggestion); 1919bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok final boolean isValidWord = AutoCorrection.isValidWord( 1920bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok mSuggest.getUnigramDictionaries(), suggestion, true); 1921bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok final boolean needsToAddToAutoDictionary = selectedATypedWordAndItsInAutoDic 1922bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok || !isValidWord; 1923bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok if (needsToAddToAutoDictionary) { 1924e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mAutoDictionary.addWord(suggestion.toString(), frequencyDelta); 1925e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka } 1926979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1927e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (mUserBigramDictionary != null) { 1928e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka CharSequence prevWord = EditingUtils.getPreviousWord(getCurrentInputConnection(), 1929e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mSentenceSeparators); 1930e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka if (!TextUtils.isEmpty(prevWord)) { 1931e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka mUserBigramDictionary.addBigrams(prevWord.toString(), suggestion.toString()); 1932979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 193332e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani } 193432e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani } 193532e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani 1936923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private boolean isCursorTouchingWord() { 1937923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project InputConnection ic = getCurrentInputConnection(); 1938923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (ic == null) return false; 1939923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence toLeft = ic.getTextBeforeCursor(1, 0); 1940923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project CharSequence toRight = ic.getTextAfterCursor(1, 0); 1941923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (!TextUtils.isEmpty(toLeft) 194255b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa && !isWordSeparator(toLeft.charAt(0)) 194355b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa && !isSuggestedPunctuation(toLeft.charAt(0))) { 1944923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 1945923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1946a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker if (!TextUtils.isEmpty(toRight) 194755b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa && !isWordSeparator(toRight.charAt(0)) 194855b10796522b871c1e04d6f2254fdff5dc7aced4Ken Wakasa && !isSuggestedPunctuation(toRight.charAt(0))) { 1949923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return true; 1950923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1951923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return false; 1952923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1953a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1954dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani private boolean sameAsTextBeforeCursor(InputConnection ic, CharSequence text) { 1955dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani CharSequence beforeText = ic.getTextBeforeCursor(text.length(), 0); 1956dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani return TextUtils.equals(text, beforeText); 1957dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani } 1958dad0e792aa064765901224af56d2a53a25bc7b7dAmith Yamasani 1959923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void revertLastWord(boolean deleteChar) { 1960923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final int length = mComposing.length(); 19619fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka if (!mHasValidSuggestions && length > 0) { 1962923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final InputConnection ic = getCurrentInputConnection(); 1963504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka final CharSequence punctuation = ic.getTextBeforeCursor(1, 0); 1964923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (deleteChar) ic.deleteSurroundingText(1, 0); 1965923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int toDelete = mCommittedLength; 1966504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka final CharSequence toTheLeft = ic.getTextBeforeCursor(mCommittedLength, 0); 1967504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka if (!TextUtils.isEmpty(toTheLeft) && isWordSeparator(toTheLeft.charAt(0))) { 1968923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project toDelete--; 1969923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1970923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project ic.deleteSurroundingText(toDelete, 0); 197130be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka // Re-insert punctuation only when the deleted character was word separator and the 197230be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka // composing text wasn't equal to the auto-corrected text. 197330be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka if (deleteChar 197430be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka && !TextUtils.isEmpty(punctuation) && isWordSeparator(punctuation.charAt(0)) 197530be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka && !TextUtils.equals(mComposing, toTheLeft)) { 1976504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka ic.commitText(mComposing, 1); 1977504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka TextEntryState.acceptedTyped(mComposing); 197830be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka ic.commitText(punctuation, 1); 1979b5d17e52fcda39d540822e615bfb7ed5074e0034satok TextEntryState.typedCharacter(punctuation.charAt(0), true, 1980b5d17e52fcda39d540822e615bfb7ed5074e0034satok WordComposer.NOT_A_COORDINATE, WordComposer.NOT_A_COORDINATE); 198130be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka // Clear composing text 198230be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka mComposing.setLength(0); 1983504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka } else { 198430be3f9845c7b1d5ae14036f816e0f7c55939f37Tadashi G. Takaoka mHasValidSuggestions = true; 1985504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka ic.setComposingText(mComposing, 1); 1986504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka TextEntryState.backspace(); 1987504e8d5171edae36ec464a5e0c72cee22bb9ac4dTadashi G. Takaoka } 1988cb3320179d39a7983874697a0aa428b127675c9dJean Chalard mHandler.cancelUpdateBigramPredictions(); 1989d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka mHandler.postUpdateSuggestions(); 1990923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } else { 1991923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); 1992923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1993923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1994923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1995923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project protected String getWordSeparators() { 1996923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return mWordSeparators; 1997923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1998a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1999923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean isWordSeparator(int code) { 2000923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project String separators = getWordSeparators(); 2001923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return separators.contains(String.valueOf((char)code)); 2002923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2003923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2004979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean isSentenceSeparator(int code) { 2005923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return mSentenceSeparators.contains(String.valueOf((char)code)); 2006923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2007923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2008923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void sendSpace() { 2009571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka sendKeyChar((char)Keyboard.CODE_SPACE); 2010b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 2011923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2012923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2013923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public boolean preferCapitalization() { 20140b4ae1f578e768eec4ada90aeb81d11acb10eb2eKen Wakasa return mWord.isFirstCharCapitalized(); 2015923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2016923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 201788fc9d44186120f9edc5cf7ec0e2af85260fed04satok // Notify that language or mode have been changed and toggleLanguage will update KeyboardID 2018c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka // according to new language or mode. 2019c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka public void onRefreshKeyboard() { 20204ab730dbd34fad323063f2ffd31ce33de746668dsatok // Reload keyboard because the current language has been changed. 2021cb97c2f1407364b24dc1a54226481a55501d1533Tadashi G. Takaoka mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), 2022b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mSubtypeSwitcher.isShortcutImeEnabled() && mVoiceProxy.isVoiceButtonEnabled(), 2023b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.isVoiceButtonOnPrimary()); 20240ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok initSuggest(); 20254b13b4f94215368c6387b2564bdaf2cbcbe4c130Tadashi G. Takaoka mKeyboardSwitcher.updateShiftState(); 202636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 202736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 202888fc9d44186120f9edc5cf7ec0e2af85260fed04satok // "reset" and "next" are used only for USE_SPACEBAR_LANGUAGE_SWITCHER. 202988fc9d44186120f9edc5cf7ec0e2af85260fed04satok private void toggleLanguage(boolean next) { 203088fc9d44186120f9edc5cf7ec0e2af85260fed04satok if (mSubtypeSwitcher.useSpacebarLanguageSwitcher()) { 203188fc9d44186120f9edc5cf7ec0e2af85260fed04satok mSubtypeSwitcher.toggleLanguage(next); 203288fc9d44186120f9edc5cf7ec0e2af85260fed04satok } 203388fc9d44186120f9edc5cf7ec0e2af85260fed04satok onRefreshKeyboard();// no need?? 203488fc9d44186120f9edc5cf7ec0e2af85260fed04satok } 203588fc9d44186120f9edc5cf7ec0e2af85260fed04satok 20365a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 20378aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka public void onSwipeDown() { 2038363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka if (mConfigSwipeDownDismissKeyboardEnabled) 2039363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka handleClose(); 2040923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2041923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 20425a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 2043e59491460b0411bed430a5ca6eca0c56c5bf18d9Tadashi G. Takaoka public void onPress(int primaryCode, boolean withSliding) { 2044cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka if (mKeyboardSwitcher.isVibrateAndSoundFeedbackRequired()) { 2045cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka vibrate(); 2046cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka playKeyClick(primaryCode); 2047cb2469ae17e0ca8a94767008fef3945cb2a3b406Tadashi G. Takaoka } 20481679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 20491679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); 2050571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) { 2051e59491460b0411bed430a5ca6eca0c56c5bf18d9Tadashi G. Takaoka switcher.onPressShift(withSliding); 2052e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka } else if (distinctMultiTouch && primaryCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) { 20536c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka switcher.onPressSymbol(); 205440a05f62edc6cdedb4365a722b48a72826ef2bf6Tadashi G. Takaoka } else { 20556c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka switcher.onOtherKeyPressed(); 2056681b102a492b7d5301c1ca87985b4c391eb5eb14Tadashi G. Takaoka } 2057dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette mAccessibilityUtils.onPress(primaryCode, switcher); 2058923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2059923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 20605a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 2061e59491460b0411bed430a5ca6eca0c56c5bf18d9Tadashi G. Takaoka public void onRelease(int primaryCode, boolean withSliding) { 20621679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka KeyboardSwitcher switcher = mKeyboardSwitcher; 20633f7d75060afb2bb7e74879bcbbdcb9700ec5c2d6Amith Yamasani // Reset any drag flags in the keyboard 20641679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); 2065571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) { 2066e59491460b0411bed430a5ca6eca0c56c5bf18d9Tadashi G. Takaoka switcher.onReleaseShift(withSliding); 2067e18bd3e323e7d7448677bb66e8149eea0169c771Tadashi G. Takaoka } else if (distinctMultiTouch && primaryCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) { 20686c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka switcher.onReleaseSymbol(); 206940a05f62edc6cdedb4365a722b48a72826ef2bf6Tadashi G. Takaoka } 2070dcade18113286a132a2f5fb508fdba836470c3fbAlan Viverette mAccessibilityUtils.onRelease(primaryCode, switcher); 2071923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2072a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 2073a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 2074123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka // receive ringer mode change and network state change. 2075923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private BroadcastReceiver mReceiver = new BroadcastReceiver() { 2076923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 2077923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onReceive(Context context, Intent intent) { 2078123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka final String action = intent.getAction(); 2079123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) { 2080123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka updateRingerMode(); 2081123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 2082123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka mSubtypeSwitcher.onNetworkStateChanged(intent); 2083123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka } 2084923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2085923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project }; 2086923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2087923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // update flags for silent mode 2088923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void updateRingerMode() { 2089923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mAudioManager == null) { 2090923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); 2091923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2092923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mAudioManager != null) { 2093923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mSilentMode = (mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL); 2094923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2095923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2096923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2097923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void playKeyClick(int primaryCode) { 2098923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // if mAudioManager is null, we don't have the ringer state yet 2099923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // mAudioManager will be set by updateRingerMode 2100923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mAudioManager == null) { 2101979f8690967ff5409fe18f5085858ccdb8e0ccf1satok if (mKeyboardSwitcher.getInputView() != null) { 2102923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project updateRingerMode(); 2103923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2104923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2105923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mSoundOn && !mSilentMode) { 2106923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // FIXME: Volume and enable should come from UI settings 2107923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // FIXME: These should be triggered after auto-repeat logic 2108923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project int sound = AudioManager.FX_KEYPRESS_STANDARD; 2109923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (primaryCode) { 2110571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_DELETE: 2111923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sound = AudioManager.FX_KEYPRESS_DELETE; 2112923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 2113571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_ENTER: 2114923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sound = AudioManager.FX_KEYPRESS_RETURN; 2115923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 2116571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka case Keyboard.CODE_SPACE: 2117923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project sound = AudioManager.FX_KEYPRESS_SPACEBAR; 2118923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project break; 2119923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2120923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mAudioManager.playSoundEffect(sound, FX_VOLUME); 2121923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2122923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2123923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2124409220583333bdf06290dd9fd42f91b5c0d1b11asatok public void vibrate() { 2125923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (!mVibrateOn) { 2126923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 2127923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 21281679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); 21291679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka if (inputView != null) { 21301679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka inputView.performHapticFeedback( 2131979f8690967ff5409fe18f5085858ccdb8e0ccf1satok HapticFeedbackConstants.KEYBOARD_TAP, 213266a787b953d703201c6b827abbee74e8cd9bb063Amith Yamasani HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); 2133923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2134923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2135923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 213671c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka public void promoteToUserDictionary(String word, int frequency) { 213734386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani if (mUserDictionary.isValidWord(word)) return; 213834386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani mUserDictionary.addWord(word, frequency); 213934386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani } 214034386e698876c0f29b2d5b54b44db1e32b562c47Amith Yamasani 214171c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka public WordComposer getCurrentWord() { 21426516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani return mWord; 21436516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani } 21446516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani 214571c353aa875f5237b1dce4e18bd4fe86ce28b58eTadashi G. Takaoka public boolean getPopupOn() { 2146979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return mPopupOn; 2147979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 2148979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 2149e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani private void updateCorrectionMode() { 21509f67e12a0e3f77985fb8bafe0db4c00e32317b9asatok // TODO: cleanup messy flags 2151e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mHasDictionary = mSuggest != null ? mSuggest.hasMainDictionary() : false; 2152e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mAutoCorrectOn = (mAutoCorrectEnabled || mQuickFixes) 2153e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani && !mInputTypeNoAutoCorrect && mHasDictionary; 215432e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani mCorrectionMode = (mAutoCorrectOn && mAutoCorrectEnabled) 2155e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani ? Suggest.CORRECTION_FULL 215632e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani : (mAutoCorrectOn ? Suggest.CORRECTION_BASIC : Suggest.CORRECTION_NONE); 2157979f8690967ff5409fe18f5085858ccdb8e0ccf1satok mCorrectionMode = (mBigramSuggestionEnabled && mAutoCorrectOn && mAutoCorrectEnabled) 2158979f8690967ff5409fe18f5085858ccdb8e0ccf1satok ? Suggest.CORRECTION_FULL_BIGRAM : mCorrectionMode; 2159e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani if (mSuggest != null) { 2160e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani mSuggest.setCorrectionMode(mCorrectionMode); 2161e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani } 2162e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani } 2163e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani 21640ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok private void updateAutoTextEnabled() { 216532e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani if (mSuggest == null) return; 21665ef096f5f601c759e8a4a888aaca91ac5ccd9974Tadashi G. Takaoka mSuggest.setQuickFixesEnabled(mQuickFixes 21674ab730dbd34fad323063f2ffd31ce33de746668dsatok && SubtypeSwitcher.getInstance().isSystemLanguageSameAsInputLanguage()); 216832e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani } 216932e1c1c338155f8a83646d725a8512b95edad4f8Amith Yamasani 21707599cfea4a2d56f4779452ec8e8742f7b9629cc0satok private void updateSuggestionVisibility(SharedPreferences prefs) { 2171458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa final Resources res = mResources; 21727599cfea4a2d56f4779452ec8e8742f7b9629cc0satok final String suggestionVisiblityStr = prefs.getString( 21739502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka Settings.PREF_SHOW_SUGGESTIONS_SETTING, 2174458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa res.getString(R.string.prefs_suggestion_visibility_default_value)); 21757599cfea4a2d56f4779452ec8e8742f7b9629cc0satok for (int visibility : SUGGESTION_VISIBILITY_VALUE_ARRAY) { 2176458249e703bded3a1cbd25a2ab2249f9366a8188Ken Wakasa if (suggestionVisiblityStr.equals(res.getString(visibility))) { 21777599cfea4a2d56f4779452ec8e8742f7b9629cc0satok mSuggestionVisibility = visibility; 21787599cfea4a2d56f4779452ec8e8742f7b9629cc0satok break; 21797599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 21807599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 21817599cfea4a2d56f4779452ec8e8742f7b9629cc0satok } 21827599cfea4a2d56f4779452ec8e8742f7b9629cc0satok 2183466741d8a78965b8509bf527344f289e50873092Mike LeBeau protected void launchSettings() { 21849502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka launchSettings(Settings.class); 2185466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 2186466741d8a78965b8509bf527344f289e50873092Mike LeBeau 2187bf96661d33d0126adb60a48880ceba1ff055d4a4satok public void launchDebugSettings() { 21889502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka launchSettings(DebugSettings.class); 2189bf96661d33d0126adb60a48880ceba1ff055d4a4satok } 2190bf96661d33d0126adb60a48880ceba1ff055d4a4satok 2191507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka protected void launchSettings(Class<? extends PreferenceActivity> settingsClass) { 2192923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project handleClose(); 2193923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project Intent intent = new Intent(); 2194466741d8a78965b8509bf527344f289e50873092Mike LeBeau intent.setClass(LatinIME.this, settingsClass); 2195923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2196923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project startActivity(intent); 2197923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2198923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 2199507495efd57074994fdc2fda78db9d5345f4a3a8Tadashi G. Takaoka private void loadSettings(EditorInfo attribute) { 2200923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Get the settings preferences 220127d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa final SharedPreferences prefs = mPrefs; 2202699e429f1913197650cc2fc2d8cb6e506be66842satok final boolean hasVibrator = VibratorCompatWrapper.getInstance(this).hasVibrator(); 2203699e429f1913197650cc2fc2d8cb6e506be66842satok mVibrateOn = hasVibrator && prefs.getBoolean(Settings.PREF_VIBRATE_ON, false); 2204f0d99b8677afdde39c16d414d44bfafcaea94b50Jean Chalard mSoundOn = prefs.getBoolean(Settings.PREF_SOUND_ON, 2205f0d99b8677afdde39c16d414d44bfafcaea94b50Jean Chalard mResources.getBoolean(R.bool.config_default_sound_enabled)); 2206728115493e14f84d5f02a4812c8086a378813364Jean Chalard 2207728115493e14f84d5f02a4812c8086a378813364Jean Chalard mPopupOn = isPopupEnabled(prefs); 22089502cc177cc53678c9ddcc01d4d046f69220e13bTadashi G. Takaoka mAutoCap = prefs.getBoolean(Settings.PREF_AUTO_CAP, true); 220989764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard mQuickFixes = isQuickFixesEnabled(prefs); 2210a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 221127d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa mAutoCorrectEnabled = isAutoCorrectEnabled(prefs); 221227d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa mBigramSuggestionEnabled = mAutoCorrectEnabled && isBigramSuggestionEnabled(prefs); 2213b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard mBigramPredictionEnabled = mBigramSuggestionEnabled && isBigramPredictionEnabled(prefs); 22141b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka loadAndSetAutoCorrectionThreshold(prefs); 2215466741d8a78965b8509bf527344f289e50873092Mike LeBeau 2216b86905943c0f1cadb2b3df9f2a58e7af84f6b27fsatok mVoiceProxy.loadSettings(attribute, prefs); 2217409220583333bdf06290dd9fd42f91b5c0d1b11asatok 2218e8f1edefeb2375a253d742c7f95e8d91677c7073Amith Yamasani updateCorrectionMode(); 22190ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok updateAutoTextEnabled(); 222027d13713bbb291d25a910f97d88a81fdbabddc0eKen Wakasa updateSuggestionVisibility(prefs); 222188fc9d44186120f9edc5cf7ec0e2af85260fed04satok 222288fc9d44186120f9edc5cf7ec0e2af85260fed04satok // This will work only when the subtype is not supported. 222388fc9d44186120f9edc5cf7ec0e2af85260fed04satok LanguageSwitcherProxy.loadSettings(); 222436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 222536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 2226b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda /** 22271b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka * Load Auto correction threshold from SharedPreferences, and modify mSuggest's threshold. 2228b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda */ 22291b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka private void loadAndSetAutoCorrectionThreshold(SharedPreferences sp) { 2230b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda // When mSuggest is not initialized, cannnot modify mSuggest's threshold. 2231b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda if (mSuggest == null) return; 22321b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // When auto correction setting is turned off, the threshold is ignored. 2233b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda if (!isAutoCorrectEnabled(sp)) return; 2234b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda 22351b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final String currentAutoCorrectionSetting = sp.getString( 22361b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka Settings.PREF_AUTO_CORRECTION_THRESHOLD, 22379ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka mResources.getString(R.string.auto_correction_threshold_mode_index_modest)); 22381b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final String[] autoCorrectionThresholdValues = mResources.getStringArray( 22399ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka R.array.auto_correction_threshold_values); 22401b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // When autoCrrectionThreshold is greater than 1.0, auto correction is virtually turned off. 22411b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka double autoCorrectionThreshold = Double.MAX_VALUE; 2242b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda try { 22431b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final int arrayIndex = Integer.valueOf(currentAutoCorrectionSetting); 22441b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka if (arrayIndex >= 0 && arrayIndex < autoCorrectionThresholdValues.length) { 22451b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka autoCorrectionThreshold = Double.parseDouble( 22461b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka autoCorrectionThresholdValues[arrayIndex]); 2247b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2248b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } catch (NumberFormatException e) { 22491b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // Whenever the threshold settings are correct, never come here. 22501b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka autoCorrectionThreshold = Double.MAX_VALUE; 22511b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka Log.w(TAG, "Cannot load auto correction threshold setting." 22521b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka + " currentAutoCorrectionSetting: " + currentAutoCorrectionSetting 22531b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka + ", autoCorrectionThresholdValues: " 22541b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka + Arrays.toString(autoCorrectionThresholdValues)); 2255b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2256b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda // TODO: This should be refactored : 22571b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka // setAutoCorrectionThreshold should be called outside of this method. 22581b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka mSuggest.setAutoCorrectionThreshold(autoCorrectionThreshold); 2259b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2260b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda 2261728115493e14f84d5f02a4812c8086a378813364Jean Chalard private boolean isPopupEnabled(SharedPreferences sp) { 2262728115493e14f84d5f02a4812c8086a378813364Jean Chalard final boolean showPopupOption = getResources().getBoolean( 2263728115493e14f84d5f02a4812c8086a378813364Jean Chalard R.bool.config_enable_show_popup_on_keypress_option); 2264728115493e14f84d5f02a4812c8086a378813364Jean Chalard if (!showPopupOption) return mResources.getBoolean(R.bool.config_default_popup_preview); 2265728115493e14f84d5f02a4812c8086a378813364Jean Chalard return sp.getBoolean(Settings.PREF_POPUP_ON, 2266728115493e14f84d5f02a4812c8086a378813364Jean Chalard mResources.getBoolean(R.bool.config_default_popup_preview)); 2267728115493e14f84d5f02a4812c8086a378813364Jean Chalard } 2268728115493e14f84d5f02a4812c8086a378813364Jean Chalard 226989764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard private boolean isQuickFixesEnabled(SharedPreferences sp) { 227089764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard final boolean showQuickFixesOption = mResources.getBoolean( 227189764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard R.bool.config_enable_quick_fixes_option); 227289764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard if (!showQuickFixesOption) { 227389764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard return isAutoCorrectEnabled(sp); 227489764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard } 227589764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard return sp.getBoolean(Settings.PREF_QUICK_FIXES, mResources.getBoolean( 227689764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard R.bool.config_default_quick_fixes)); 227789764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard } 227889764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard 2279b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda private boolean isAutoCorrectEnabled(SharedPreferences sp) { 22801b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final String currentAutoCorrectionSetting = sp.getString( 22811b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka Settings.PREF_AUTO_CORRECTION_THRESHOLD, 22829ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka mResources.getString(R.string.auto_correction_threshold_mode_index_modest)); 22831b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka final String autoCorrectionOff = mResources.getString( 22849ecad8c2e8571ece6f3f7fbb19ceda5be7866cf0Tadashi G. Takaoka R.string.auto_correction_threshold_mode_index_off); 22851b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka return !currentAutoCorrectionSetting.equals(autoCorrectionOff); 2286b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2287b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda 2288b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda private boolean isBigramSuggestionEnabled(SharedPreferences sp) { 228989764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard final boolean showBigramSuggestionsOption = mResources.getBoolean( 229089764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard R.bool.config_enable_bigram_suggestions_option); 229189764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard if (!showBigramSuggestionsOption) { 229289764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard return isAutoCorrectEnabled(sp); 229389764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard } 229489764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard return sp.getBoolean(Settings.PREF_BIGRAM_SUGGESTIONS, mResources.getBoolean( 229589764ad4ac5415fb9753c38671b1fa18b9cdd390Jean Chalard R.bool.config_default_bigram_suggestions)); 2296b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda } 2297b1abda8d62d654e876c4f781a07d724922c736e4Mitsuhiro Shimoda 2298b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard private boolean isBigramPredictionEnabled(SharedPreferences sp) { 2299b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard return sp.getBoolean(Settings.PREF_BIGRAM_PREDICTIONS, mResources.getBoolean( 2300b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard R.bool.config_default_bigram_prediction)); 2301b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard } 2302b50591295d7c4ff7bb46ddf3e609d0046eb64d18Jean Chalard 23036a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani private void initSuggestPuncList() { 23047e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka if (mSuggestPuncs != null || mSuggestPuncList != null) 23057e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka return; 23067e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka SuggestedWords.Builder builder = new SuggestedWords.Builder(); 23077e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka String puncs = mResources.getString(R.string.suggested_punctuations); 23087e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka if (puncs != null) { 23097e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka for (int i = 0; i < puncs.length(); i++) { 23107e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka builder.addWord(puncs.subSequence(i, i + 1)); 23116a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 23126a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 23137e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka mSuggestPuncList = builder.build(); 23147e181fe1010c8eac7814cc67a0c4b3864a10b151Tadashi G. Takaoka mSuggestPuncs = puncs; 23156a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 23166a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani 2317979f8690967ff5409fe18f5085858ccdb8e0ccf1satok private boolean isSuggestedPunctuation(int code) { 2318979f8690967ff5409fe18f5085858ccdb8e0ccf1satok return mSuggestPuncs.contains(String.valueOf((char)code)); 2319979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 2320979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 23212fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private void showSubtypeSelectorAndSettings() { 232285996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final CharSequence title = getString(R.string.english_ime_input_options); 232385996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final CharSequence[] items = new CharSequence[] { 232485996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka // TODO: Should use new string "Select active input modes". 232585996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka getString(R.string.language_selection_title), 232685996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka getString(R.string.english_ime_settings), 232785996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka }; 232885996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { 23292fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka @Override 23302fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka public void onClick(DialogInterface di, int position) { 23312fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka di.dismiss(); 23322fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka switch (position) { 233385996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka case 0: 23342cff4d7e4abdb192151f9b4027fc93fe28a8bdaasatok Intent intent = CompatUtils.getInputLanguageSelectionIntent( 23352cff4d7e4abdb192151f9b4027fc93fe28a8bdaasatok mInputMethodId, Intent.FLAG_ACTIVITY_NEW_TASK 23362fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 23372fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka | Intent.FLAG_ACTIVITY_CLEAR_TOP); 23382fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka startActivity(intent); 23392fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka break; 2340aa0458f917bb823efab6245f08c65e8f2f7327acKen Wakasa case 1: 2341aa0458f917bb823efab6245f08c65e8f2f7327acKen Wakasa launchSettings(); 2342aa0458f917bb823efab6245f08c65e8f2f7327acKen Wakasa break; 23432fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } 23442fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } 234585996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka }; 234685996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka showOptionsMenuInternal(title, items, listener); 23472fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } 2348923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 23492fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private void showOptionsMenu() { 235085996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final CharSequence title = getString(R.string.english_ime_input_options); 235185996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final CharSequence[] items = new CharSequence[] { 235285996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka getString(R.string.selectInputMethod), 235385996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka getString(R.string.english_ime_settings), 235485996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka }; 235585996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { 23565a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 2357923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void onClick(DialogInterface di, int position) { 2358923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project di.dismiss(); 2359923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (position) { 236085996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka case 0: 2361ea55bf5df7d26d12b36c47141bfbac5730c3929aTadashi G. Takaoka mImm.showInputMethodPicker(); 23622fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka break; 236385996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka case 1: 2364ea55bf5df7d26d12b36c47141bfbac5730c3929aTadashi G. Takaoka launchSettings(); 23652fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka break; 2366923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2367923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 236885996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka }; 236985996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka showOptionsMenuInternal(title, items, listener); 23702fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } 23712fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka 237285996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka private void showOptionsMenuInternal(CharSequence title, CharSequence[] items, 237385996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka DialogInterface.OnClickListener listener) { 237418e15a1e5e30cf200e935e43a73edef25682de27Ken Wakasa final IBinder windowToken = mKeyboardSwitcher.getInputView().getWindowToken(); 237518e15a1e5e30cf200e935e43a73edef25682de27Ken Wakasa if (windowToken == null) return; 23762fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka AlertDialog.Builder builder = new AlertDialog.Builder(this); 23772fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka builder.setCancelable(true); 23782fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka builder.setIcon(R.drawable.ic_dialog_keyboard); 23792fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka builder.setNegativeButton(android.R.string.cancel, null); 238085996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka builder.setItems(items, listener); 238185996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka builder.setTitle(title); 2382923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mOptionsDialog = builder.create(); 2383a2ad96d95986eb61c3d2d5abce154fb4c3803cacTadashi G. Takaoka mOptionsDialog.setCanceledOnTouchOutside(true); 2384923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project Window window = mOptionsDialog.getWindow(); 2385923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project WindowManager.LayoutParams lp = window.getAttributes(); 238618e15a1e5e30cf200e935e43a73edef25682de27Ken Wakasa lp.token = windowToken; 2387923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 2388923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project window.setAttributes(lp); 2389923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); 2390923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mOptionsDialog.show(); 2391923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2392923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 23937e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka @Override 23947e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { 2395923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.dump(fd, fout, args); 2396a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 2397923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final Printer p = new PrintWriterPrinter(fout); 2398923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println("LatinIME state :"); 2399923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" Keyboard mode = " + mKeyboardSwitcher.getKeyboardMode()); 2400923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mComposing=" + mComposing.toString()); 24019fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka p.println(" mIsSuggestionsRequested=" + mIsSettingsSuggestionStripOn); 2402923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mCorrectionMode=" + mCorrectionMode); 24039fb8c6dd48dfa4e45827628a866d9b13c4c6c799Tadashi G. Takaoka p.println(" mHasValidSuggestions=" + mHasValidSuggestions); 2404923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mAutoCorrectOn=" + mAutoCorrectOn); 2405923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mAutoSpace=" + mAutoSpace); 24061b1f7f907f6c7d6e849c88ca06c3608bc84d7c5fTadashi G. Takaoka p.println(" mApplicationSpecifiedCompletionOn=" + mApplicationSpecifiedCompletionOn); 2407923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" TextEntryState.state=" + TextEntryState.getState()); 2408923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mSoundOn=" + mSoundOn); 2409923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println(" mVibrateOn=" + mVibrateOn); 2410979f8690967ff5409fe18f5085858ccdb8e0ccf1satok p.println(" mPopupOn=" + mPopupOn); 2411923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 24126e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani 2413923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // Characters per second measurement 2414a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 2415923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private long mLastCpsTime; 2416923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private static final int CPS_BUFFER_SIZE = 16; 2417923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private long[] mCpsIntervals = new long[CPS_BUFFER_SIZE]; 2418923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private int mCpsIndex; 2419a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 2420923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project private void measureCps() { 2421923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project long now = System.currentTimeMillis(); 2422923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (mLastCpsTime == 0) mLastCpsTime = now - 100; // Initial 2423923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCpsIntervals[mCpsIndex] = now - mLastCpsTime; 2424923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mLastCpsTime = now; 2425923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project mCpsIndex = (mCpsIndex + 1) % CPS_BUFFER_SIZE; 2426923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project long total = 0; 2427923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project for (int i = 0; i < CPS_BUFFER_SIZE; i++) total += mCpsIntervals[i]; 2428923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project System.out.println("CPS = " + ((CPS_BUFFER_SIZE * 1000f) / total)); 2429923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 2430923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project} 2431