1923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/* 2443c360d0afdbab091994244f045f4756feaf2b4Jean-Baptiste Queru * Copyright (C) 2008 The Android Open Source Project 3c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * 48aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); 58aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * you may not use this file except in compliance with the License. 68aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * You may obtain a copy of the License at 7a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker * 88aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * 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 118aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, 128aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * See the License for the specific language governing permissions and 148aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka * limitations under 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 199342484e8d573a40f470b6a593df31c602fa4076Ken Wakasaimport static com.android.inputmethod.latin.common.Constants.ImeOption.FORCE_ASCII; 209342484e8d573a40f470b6a593df31c602fa4076Ken Wakasaimport static com.android.inputmethod.latin.common.Constants.ImeOption.NO_MICROPHONE; 219342484e8d573a40f470b6a593df31c602fa4076Ken Wakasaimport static com.android.inputmethod.latin.common.Constants.ImeOption.NO_MICROPHONE_COMPAT; 221cb08acaf3b4d58cbf4cb65f9fc3990b39e33f00Tadashi G. Takaoka 23604158669b407a40cd0f23538fad4dce5d738f24Mohammadinamul Sheikimport android.Manifest.permission; 24923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.app.AlertDialog; 25923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.BroadcastReceiver; 26923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.Context; 27923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.DialogInterface; 286abc852255072e9c5741a7d8f264bec99b0ce14eTadashi G. Takaokaimport android.content.DialogInterface.OnClickListener; 29923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.Intent; 30923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.IntentFilter; 31923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.content.res.Configuration; 3236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.content.res.Resources; 336c04339c5aadb5118b0e0a8178b3d569956bbad7Seigo Nonakaimport android.graphics.Color; 34923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.inputmethodservice.InputMethodService; 35923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.media.AudioManager; 3660b59042d1f5a1449de049a7f7adb3d6e40b8b06Yohei Yukawaimport android.os.Build; 37923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.Debug; 3881d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaokaimport android.os.IBinder; 39923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.os.Message; 402dae79b1966a7970c25c8b79beec1c95c13f6c87Tadashi G. Takaokaimport android.preference.PreferenceManager; 41e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaokaimport android.text.InputType; 42923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.util.Log; 43923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.util.PrintWriterPrinter; 44923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.util.Printer; 455eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalardimport android.util.SparseArray; 4637beaf1529a61228d6240736937789e5622b29edTadashi G. Takaokaimport android.view.Gravity; 474e1a558ee8d7747b71dba5aac86a7c9003d6f57dJean Chalardimport android.view.KeyEvent; 48923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.View; 49c160a3932f74fea72c5347798c001d4ae961864cKen Wakasaimport android.view.ViewGroup.LayoutParams; 5013d6ecc4c275b9e9c38c7713bb2c69d37f3467f3Tadashi G. Takaokaimport android.view.Window; 5113d6ecc4c275b9e9c38c7713bb2c69d37f3467f3Tadashi G. Takaokaimport android.view.WindowManager; 52923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.inputmethod.CompletionInfo; 53923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectimport android.view.inputmethod.EditorInfo; 549cc2c94c8b4bfd4e00e5d3478b9f6e520e791bc5Tadashi G. Takaokaimport android.view.inputmethod.InputMethodSubtype; 55c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka 565ac4638f999db4fea8a9e24171dbceb640a10858Alan Viveretteimport com.android.inputmethod.accessibility.AccessibilityUtils; 5715f6d4ae34664ea3d92827a2c3003198c0bac70bTadashi G. Takaokaimport com.android.inputmethod.annotations.UsedForTesting; 5860b59042d1f5a1449de049a7f7adb3d6e40b8b06Yohei Yukawaimport com.android.inputmethod.compat.BuildCompatUtils; 59809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawaimport com.android.inputmethod.compat.EditorInfoCompatUtils; 60fb955693d4bb0c8d39092250a4208e385b8a31a7Ken Wakasaimport com.android.inputmethod.compat.InputMethodServiceCompatUtils; 61809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawaimport com.android.inputmethod.compat.InputMethodSubtypeCompatUtils; 6215480481be790c913b0117d0841565efd399cd01Tadashi G. Takaokaimport com.android.inputmethod.compat.ViewOutlineProviderCompatUtils; 6315480481be790c913b0117d0841565efd399cd01Tadashi G. Takaokaimport com.android.inputmethod.compat.ViewOutlineProviderCompatUtils.InsetsUpdater; 641061bfdb34bbcb63bf0046eec42313d264ac33faJean Chalardimport com.android.inputmethod.dictionarypack.DictionaryPackConstants; 65a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalardimport com.android.inputmethod.event.Event; 665eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalardimport com.android.inputmethod.event.HardwareEventDecoder; 675eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalardimport com.android.inputmethod.event.HardwareKeyboardEventDecoder; 68a1bf550294dfb5e6e7e5eba78a8db491c5bab2d4Jean Chalardimport com.android.inputmethod.event.InputTransaction; 69c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaokaimport com.android.inputmethod.keyboard.Keyboard; 70c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardActionListener; 716b7100fecaaaf0e8e42c4d2ccebac165e89e79bfTadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardId; 72c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardSwitcher; 73c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaokaimport com.android.inputmethod.keyboard.MainKeyboardView; 749666a228153bb2269da8983762bdd47e448f2cecYuichiro Hanadaimport com.android.inputmethod.latin.Suggest.OnGetSuggestedWordsCallback; 759310f42a36eabe99ed7dcd3b835d6cdaa3c6fdcaJean Chalardimport com.android.inputmethod.latin.SuggestedWords.SuggestedWordInfo; 769342484e8d573a40f470b6a593df31c602fa4076Ken Wakasaimport com.android.inputmethod.latin.common.Constants; 775b91b551e5ffaf2c2e691dfbd434f21c82293986Jean Chalardimport com.android.inputmethod.latin.common.CoordinateUtils; 7836799b2aa2982ec17341cd2c5ed81e608bcee8c6Jean Chalardimport com.android.inputmethod.latin.common.InputPointers; 792dae79b1966a7970c25c8b79beec1c95c13f6c87Tadashi G. Takaokaimport com.android.inputmethod.latin.define.DebugFlags; 805a5ee95faead8a2ae749067716481e86faf5f113Tadashi G. Takaokaimport com.android.inputmethod.latin.define.ProductionFlags; 817bd2a75ca180cb5da8ba75500163aa06f332caacJean Chalardimport com.android.inputmethod.latin.inputlogic.InputLogic; 82604158669b407a40cd0f23538fad4dce5d738f24Mohammadinamul Sheikimport com.android.inputmethod.latin.permissions.PermissionsManager; 83f1457e7a221082688b6399853e84e77948633c7bKeisuke Kuroyanagiimport com.android.inputmethod.latin.personalization.PersonalizationHelper; 84a7d2fc6befa1b16883200a653fc01deb4d94944dKen Wakasaimport com.android.inputmethod.latin.settings.Settings; 85a7d2fc6befa1b16883200a653fc01deb4d94944dKen Wakasaimport com.android.inputmethod.latin.settings.SettingsActivity; 86a7d2fc6befa1b16883200a653fc01deb4d94944dKen Wakasaimport com.android.inputmethod.latin.settings.SettingsValues; 874702671ea4feb0c79a879e2e3013afdd6ed800b1Tadashi G. Takaokaimport com.android.inputmethod.latin.suggestions.SuggestionStripView; 88ade1aa55b6be938a44b92f7ca6829c53c6258664Jean Chalardimport com.android.inputmethod.latin.suggestions.SuggestionStripViewAccessor; 89c92c883fdf2287b49392692fa2e8d109dc26f785David Fadenimport com.android.inputmethod.latin.touchinputconsumer.GestureConsumer; 904be6198cb73cc24e10834153c4e049644ed187e3Tadashi G. Takaokaimport com.android.inputmethod.latin.utils.ApplicationUtils; 919b46ddc1d51fac37f970e108f7d93eb9ea11e1beTadashi G. Takaokaimport com.android.inputmethod.latin.utils.DialogUtils; 92342e81e7a6cfec8054a8978a9bb84b68e76a01b0Tadashi G. Takaokaimport com.android.inputmethod.latin.utils.ImportantNoticeUtils; 93e28eba5074664d5716b8e58b8d0a235746b261ebKen Wakasaimport com.android.inputmethod.latin.utils.IntentUtils; 94bfaf349c3554e11af8227a5f0807a74107a93069Ken Wakasaimport com.android.inputmethod.latin.utils.JniUtils; 952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaimport com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper; 96dc0f7ca167df5b49daa4707d4f737f683b052dabYohei Yukawaimport com.android.inputmethod.latin.utils.StatsUtils; 97aabb3512791979a00c0ab50c0be808f46d18cbe6Jatin Mataniimport com.android.inputmethod.latin.utils.StatsUtilsManager; 98bcd30bf3e74c7c10d5b69a54cdf90c6b682a0747Tadashi G. Takaokaimport com.android.inputmethod.latin.utils.SubtypeLocaleUtils; 9937beaf1529a61228d6240736937789e5622b29edTadashi G. Takaokaimport com.android.inputmethod.latin.utils.ViewLayoutUtils; 100923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 101466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport java.io.FileDescriptor; 102466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport java.io.PrintWriter; 1034ee186920e642ae8ebe0b6c97dfdceb0ad2fdeefJean Chalardimport java.util.ArrayList; 1041fa3e9044f4bb7d1eb62118c94a2223af69c14b0Keisuke Kuroyanagiimport java.util.List; 105466741d8a78965b8509bf527344f289e50873092Mike LeBeauimport java.util.Locale; 1069f1fe87580adc9ca041fc044f88341fa262c82a2Keisuke Kuroyanagiimport java.util.concurrent.TimeUnit; 107466741d8a78965b8509bf527344f289e50873092Mike LeBeau 108c4ffa235e5490c3cba211b469c7f125d162f9f86Tadashi G. Takaokaimport javax.annotation.Nonnull; 109c4ffa235e5490c3cba211b469c7f125d162f9f86Tadashi G. Takaoka 110923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/** 111923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Input method implementation for Qwerty'ish keyboard. 112923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */ 113c9aaba125365cf767356a4bea442153e95bbf6a1Jean Chalardpublic class LatinIME extends InputMethodService implements KeyboardActionListener, 114ade1aa55b6be938a44b92f7ca6829c53c6258664Jean Chalard SuggestionStripView.Listener, SuggestionStripViewAccessor, 115a1035be6d877cafda95b2761f9697474b79deeb8Keisuke Kuroyanagi DictionaryFacilitator.DictionaryInitializationListener, 116604158669b407a40cd0f23538fad4dce5d738f24Mohammadinamul Sheik PermissionsManager.PermissionsResultCallback { 1175f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka static final String TAG = LatinIME.class.getSimpleName(); 118409220583333bdf06290dd9fd42f91b5c0d1b11asatok private static final boolean TRACE = false; 119a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1209e347d3d448e48229c46aad394ec9bd60cd5807bsatok private static final int EXTENDED_TOUCHABLE_REGION_HEIGHT = 100; 121ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka private static final int PERIOD_FOR_AUDIO_AND_HAPTIC_FEEDBACK_IN_KEY_REPEAT = 2; 1227b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu private static final int PENDING_IMS_CALLBACK_DURATION_MILLIS = 800; 1235f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka static final long DELAY_WAIT_FOR_DICTIONARY_LOAD_MILLIS = TimeUnit.SECONDS.toMillis(2); 1245f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka static final long DELAY_DEALLOCATE_MEMORY_MILLIS = TimeUnit.SECONDS.toMillis(10); 125ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka 126cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard /** 127cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard * The name of the scheme used by the Package Manager to warn of a new package installation, 128cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard * replacement or removal. 129cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard */ 130cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard private static final String SCHEME_PACKAGE = "package"; 131cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard 1325f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka final Settings mSettings; 13315acbdc9050a04f3c5d8724bb3902a57084c96dbJatin Matani private final DictionaryFacilitator mDictionaryFacilitator = 134b684d2d2e4ae4a43a6f499a263a421760fc5c175Jatin Matani DictionaryFacilitatorProvider.getDictionaryFacilitator( 135b684d2d2e4ae4a43a6f499a263a421760fc5c175Jatin Matani false /* isNeededForSpellChecking */); 1365f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka final InputLogic mInputLogic = new InputLogic(this /* LatinIME */, 137a1035be6d877cafda95b2761f9697474b79deeb8Keisuke Kuroyanagi this /* SuggestionStripViewAccessor */, mDictionaryFacilitator); 1385eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard // We expect to have only one decoder in almost all cases, hence the default capacity of 1. 1395eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard // If it turns out we need several, it will get grown seamlessly. 140a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka final SparseArray<HardwareEventDecoder> mHardwareEventDecoders = new SparseArray<>(1); 14117c7ffeb1e10348227c5dff1c319d2099c1b5d0eJean Chalard 1428fdff5a11129827e88ce9f5bc462e18f613c19a3Tadashi G. Takaoka // TODO: Move these {@link View}s to {@link KeyboardSwitcher}. 1438fdff5a11129827e88ce9f5bc462e18f613c19a3Tadashi G. Takaoka private View mInputView; 14415480481be790c913b0117d0841565efd399cd01Tadashi G. Takaoka private InsetsUpdater mInsetsUpdater; 1454702671ea4feb0c79a879e2e3013afdd6ed800b1Tadashi G. Takaoka private SuggestionStripView mSuggestionStripView; 1467bd2a75ca180cb5da8ba75500163aa06f332caacJean Chalard 1476fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka private RichInputMethodManager mRichImm; 14815f6d4ae34664ea3d92827a2c3003198c0bac70bTadashi G. Takaoka @UsedForTesting final KeyboardSwitcher mKeyboardSwitcher; 1491931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka private final SubtypeState mSubtypeState = new SubtypeState(); 1501fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic private EmojiAltPhysicalKeyDetector mEmojiAltPhysicalKeyDetector; 151aabb3512791979a00c0ab50c0be808f46d18cbe6Jatin Matani private StatsUtilsManager mStatsUtilsManager; 15288f282de0dbb92c7d423c30a84395893d6765092Tadashi G. Takaoka // Working variable for {@link #startShowingInputView()} and 15388f282de0dbb92c7d423c30a84395893d6765092Tadashi G. Takaoka // {@link #onEvaluateInputViewShown()}. 15488f282de0dbb92c7d423c30a84395893d6765092Tadashi G. Takaoka private boolean mIsExecutingStartShowingInputView; 155a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 156cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard // Object for reacting to adding/removing a dictionary pack. 15723246ed18d9b26d8a7673140c00e060022be935bKeisuke Kuroyanagi private final BroadcastReceiver mDictionaryPackInstallReceiver = 158efd26bb3192722c2980098a6f36dff6006e8896aKurt Partridge new DictionaryPackInstallBroadcastReceiver(this); 159cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard 16023246ed18d9b26d8a7673140c00e060022be935bKeisuke Kuroyanagi private final BroadcastReceiver mDictionaryDumpBroadcastReceiver = 16136c7a62dffb7f5b6728fa0850c1f63aee0f14d80Keisuke Kuroyanagi new DictionaryDumpBroadcastReceiver(this); 16236c7a62dffb7f5b6728fa0850c1f63aee0f14d80Keisuke Kuroyanagi 16313d6ecc4c275b9e9c38c7713bb2c69d37f3467f3Tadashi G. Takaoka private AlertDialog mOptionsDialog; 16413d6ecc4c275b9e9c38c7713bb2c69d37f3467f3Tadashi G. Takaoka 165fb955693d4bb0c8d39092250a4208e385b8a31a7Ken Wakasa private final boolean mIsHardwareAcceleratedDrawingEnabled; 166fb955693d4bb0c8d39092250a4208e385b8a31a7Ken Wakasa 167c92c883fdf2287b49392692fa2e8d109dc26f785David Faden private GestureConsumer mGestureConsumer = GestureConsumer.NULL_GESTURE_CONSUMER; 168c92c883fdf2287b49392692fa2e8d109dc26f785David Faden 1694f0d290c5d112ebac434bd8de4635f7d42ea2df0Ken Wakasa public final UIHandler mHandler = new UIHandler(this); 170d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 1712fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa public static final class UIHandler extends LeakGuardHandlerWrapper<LatinIME> { 17227e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka private static final int MSG_UPDATE_SHIFT_STATE = 0; 17327e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka private static final int MSG_PENDING_IMS_CALLBACK = 1; 17427e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka private static final int MSG_UPDATE_SUGGESTION_STRIP = 2; 175f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka private static final int MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP = 3; 1766a114fa700d3ca73c608e1291b74bbbdd5a1a7b7Jean Chalard private static final int MSG_RESUME_SUGGESTIONS = 4; 177673c727b7a42e2cee2df4415111bfa94a0a2df3bJean Chalard private static final int MSG_REOPEN_DICTIONARIES = 5; 178a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard private static final int MSG_UPDATE_TAIL_BATCH_INPUT_COMPLETED = 6; 179f1d8aa46f9172c2d8864d0d2161aa8220d036cc9Jean Chalard private static final int MSG_RESET_CACHES = 7; 180fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard private static final int MSG_WAIT_FOR_DICTIONARY_LOAD = 8; 1817b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu private static final int MSG_DEALLOCATE_MEMORY = 9; 1829444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard private static final int MSG_RESUME_SUGGESTIONS_FOR_START_INPUT = 10; 183809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa private static final int MSG_SWITCH_LANGUAGE_AUTOMATICALLY = 11; 1842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // Update this when adding new messages 185809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa private static final int MSG_LAST = MSG_SWITCH_LANGUAGE_AUTOMATICALLY; 186f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka 187908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada private static final int ARG1_NOT_GESTURE_INPUT = 0; 188f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka private static final int ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 1; 189908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada private static final int ARG1_SHOW_GESTURE_FLOATING_PREVIEW_TEXT = 2; 190084c9961f4ede347fbfb719ce1075a10b93867c3Jean Chalard private static final int ARG2_UNUSED = 0; 191fca2c4b4398ae2aa505de223d602c5b3dd98faffJean Chalard private static final int ARG1_TRUE = 1; 1924c0c638a189c1073b1fb6e43fe5fddb6f9932038Tadashi G. Takaoka 193a61b7245b030395451b4c42ec218a946aa95e030Yohei Yukawa private int mDelayInMillisecondsToUpdateSuggestions; 194a61b7245b030395451b4c42ec218a946aa95e030Yohei Yukawa private int mDelayInMillisecondsToUpdateShiftState; 19538f55b36c3992a580cf7e20668b1eb72a4eb2431Tadashi G. Takaoka 196c4ffa235e5490c3cba211b469c7f125d162f9f86Tadashi G. Takaoka public UIHandler(@Nonnull final LatinIME ownerInstance) { 1972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa super(ownerInstance); 19810dff76856a98b6eec86a53d3d07fdc9708037b7Tadashi G. Takaoka } 199175acb8205fcc2a91de4059e8a12af49484af784Tadashi G. Takaoka 20010dff76856a98b6eec86a53d3d07fdc9708037b7Tadashi G. Takaoka public void onCreate() { 20198534dc065a828525129dc23aaca3ebd8834514cKen Wakasa final LatinIME latinIme = getOwnerInstance(); 20298534dc065a828525129dc23aaca3ebd8834514cKen Wakasa if (latinIme == null) { 20398534dc065a828525129dc23aaca3ebd8834514cKen Wakasa return; 20498534dc065a828525129dc23aaca3ebd8834514cKen Wakasa } 20598534dc065a828525129dc23aaca3ebd8834514cKen Wakasa final Resources res = latinIme.getResources(); 206bea17c49ec23bf0f646cb548445c7756aa50d233Yohei Yukawa mDelayInMillisecondsToUpdateSuggestions = res.getInteger( 207bea17c49ec23bf0f646cb548445c7756aa50d233Yohei Yukawa R.integer.config_delay_in_milliseconds_to_update_suggestions); 208bea17c49ec23bf0f646cb548445c7756aa50d233Yohei Yukawa mDelayInMillisecondsToUpdateShiftState = res.getInteger( 209bea17c49ec23bf0f646cb548445c7756aa50d233Yohei Yukawa R.integer.config_delay_in_milliseconds_to_update_shift_state); 2104f0d290c5d112ebac434bd8de4635f7d42ea2df0Ken Wakasa } 2114f0d290c5d112ebac434bd8de4635f7d42ea2df0Ken Wakasa 212923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 213f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void handleMessage(final Message msg) { 2142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final LatinIME latinIme = getOwnerInstance(); 21598534dc065a828525129dc23aaca3ebd8834514cKen Wakasa if (latinIme == null) { 21698534dc065a828525129dc23aaca3ebd8834514cKen Wakasa return; 21798534dc065a828525129dc23aaca3ebd8834514cKen Wakasa } 2184f0d290c5d112ebac434bd8de4635f7d42ea2df0Ken Wakasa final KeyboardSwitcher switcher = latinIme.mKeyboardSwitcher; 219923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project switch (msg.what) { 220dc1b84d96cf7fc4ee21cf7df8a12bc7913ffd64eJean Chalard case MSG_UPDATE_SUGGESTION_STRIP: 221151761a2764c09c0e5bc48c68e0c804aeaf22d11Jean Chalard cancelUpdateSuggestionStrip(); 2222a6de7903c1aabad9911638f90cfca12ce64c1e1Jean Chalard latinIme.mInputLogic.performUpdateSuggestionStripSync( 223b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard latinIme.mSettings.getCurrent(), msg.arg1 /* inputStyle */); 224d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 225d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka case MSG_UPDATE_SHIFT_STATE: 2268ab4ae4377fca97cb9ef05c615c5a59bc4bc3d8cJean Chalard switcher.requestUpdatingShiftState(latinIme.getCurrentAutoCapsState(), 2278ab4ae4377fca97cb9ef05c615c5a59bc4bc3d8cJean Chalard latinIme.getCurrentRecapitalizeState()); 228d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka break; 229f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka case MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP: 230908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada if (msg.arg1 == ARG1_NOT_GESTURE_INPUT) { 231084c9961f4ede347fbfb719ce1075a10b93867c3Jean Chalard final SuggestedWords suggestedWords = (SuggestedWords) msg.obj; 232fa7075768da25341bf84e9f87bba09356961e2e8Jean Chalard latinIme.showSuggestionStrip(suggestedWords); 233908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada } else { 234908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada latinIme.showGesturePreviewAndSuggestionStrip((SuggestedWords) msg.obj, 235908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada msg.arg1 == ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT); 236908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada } 237f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka break; 2386a114fa700d3ca73c608e1291b74bbbdd5a1a7b7Jean Chalard case MSG_RESUME_SUGGESTIONS: 239221df9e59aade0860624aeeb9b7b25311584c93aJean Chalard latinIme.mInputLogic.restartSuggestionsOnWordTouchedByCursor( 2409444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard latinIme.mSettings.getCurrent(), false /* forStartInput */, 2419444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard latinIme.mKeyboardSwitcher.getCurrentKeyboardScriptId()); 2429444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard break; 2439444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard case MSG_RESUME_SUGGESTIONS_FOR_START_INPUT: 2449444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard latinIme.mInputLogic.restartSuggestionsOnWordTouchedByCursor( 2459444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard latinIme.mSettings.getCurrent(), true /* forStartInput */, 24635c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard latinIme.mKeyboardSwitcher.getCurrentKeyboardScriptId()); 2476a114fa700d3ca73c608e1291b74bbbdd5a1a7b7Jean Chalard break; 248673c727b7a42e2cee2df4415111bfa94a0a2df3bJean Chalard case MSG_REOPEN_DICTIONARIES: 2496345562e2b351221a9bc0341f7dbd26095290b64Jean Chalard // We need to re-evaluate the currently composing word in case the script has 2506345562e2b351221a9bc0341f7dbd26095290b64Jean Chalard // changed. 251fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard postWaitForDictionaryLoad(); 2521c0876dc49eee44170cb86ba3d78e759d5bbd573Jean Chalard latinIme.resetDictionaryFacilitatorIfNecessary(); 253673c727b7a42e2cee2df4415111bfa94a0a2df3bJean Chalard break; 254a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard case MSG_UPDATE_TAIL_BATCH_INPUT_COMPLETED: 255c92c883fdf2287b49392692fa2e8d109dc26f785David Faden final SuggestedWords suggestedWords = (SuggestedWords) msg.obj; 256a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard latinIme.mInputLogic.onUpdateTailBatchInputCompleted( 257a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard latinIme.mSettings.getCurrent(), 258c92c883fdf2287b49392692fa2e8d109dc26f785David Faden suggestedWords, latinIme.mKeyboardSwitcher); 259c92c883fdf2287b49392692fa2e8d109dc26f785David Faden latinIme.onTailBatchInputResultShown(suggestedWords); 260908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada break; 261f1d8aa46f9172c2d8864d0d2161aa8220d036cc9Jean Chalard case MSG_RESET_CACHES: 262ab80b41a0dee298837b1358457768ee5ac0fc79eJean Chalard final SettingsValues settingsValues = latinIme.mSettings.getCurrent(); 263dd31a2dedf3259662cacac9baad638ec10a0baebJean Chalard if (latinIme.mInputLogic.retryResetCachesAndReturnSuccess( 264bea17c49ec23bf0f646cb548445c7756aa50d233Yohei Yukawa msg.arg1 == ARG1_TRUE /* tryResumeSuggestions */, 265ab80b41a0dee298837b1358457768ee5ac0fc79eJean Chalard msg.arg2 /* remainingTries */, this /* handler */)) { 266ab80b41a0dee298837b1358457768ee5ac0fc79eJean Chalard // If we were able to reset the caches, then we can reload the keyboard. 267ab80b41a0dee298837b1358457768ee5ac0fc79eJean Chalard // Otherwise, we'll do it when we can. 268ab80b41a0dee298837b1358457768ee5ac0fc79eJean Chalard latinIme.mKeyboardSwitcher.loadKeyboard(latinIme.getCurrentInputEditorInfo(), 269f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard settingsValues, latinIme.getCurrentAutoCapsState(), 27026611120c9083ffc342b4e0f8c78a9aef2b6db2eJean Chalard latinIme.getCurrentRecapitalizeState()); 271ab80b41a0dee298837b1358457768ee5ac0fc79eJean Chalard } 272f1d8aa46f9172c2d8864d0d2161aa8220d036cc9Jean Chalard break; 273fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard case MSG_WAIT_FOR_DICTIONARY_LOAD: 274fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard Log.i(TAG, "Timeout waiting for dictionary load"); 275fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard break; 2767b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu case MSG_DEALLOCATE_MEMORY: 2777b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu latinIme.deallocateMemory(); 2787b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu break; 279809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa case MSG_SWITCH_LANGUAGE_AUTOMATICALLY: 280809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa latinIme.switchLanguage((InputMethodSubtype)msg.obj); 281809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa break; 282923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 283923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 284d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 285b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard public void postUpdateSuggestionStrip(final int inputStyle) { 286b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard sendMessageDelayed(obtainMessage(MSG_UPDATE_SUGGESTION_STRIP, inputStyle, 287a61b7245b030395451b4c42ec218a946aa95e030Yohei Yukawa 0 /* ignored */), mDelayInMillisecondsToUpdateSuggestions); 288d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 289d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 290673c727b7a42e2cee2df4415111bfa94a0a2df3bJean Chalard public void postReopenDictionaries() { 291673c727b7a42e2cee2df4415111bfa94a0a2df3bJean Chalard sendMessage(obtainMessage(MSG_REOPEN_DICTIONARIES)); 292673c727b7a42e2cee2df4415111bfa94a0a2df3bJean Chalard } 293673c727b7a42e2cee2df4415111bfa94a0a2df3bJean Chalard 2949444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard private void postResumeSuggestionsInternal(final boolean shouldDelay, 2959444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard final boolean forStartInput) { 29698534dc065a828525129dc23aaca3ebd8834514cKen Wakasa final LatinIME latinIme = getOwnerInstance(); 29798534dc065a828525129dc23aaca3ebd8834514cKen Wakasa if (latinIme == null) { 29898534dc065a828525129dc23aaca3ebd8834514cKen Wakasa return; 29998534dc065a828525129dc23aaca3ebd8834514cKen Wakasa } 300a61b7245b030395451b4c42ec218a946aa95e030Yohei Yukawa if (!latinIme.mSettings.getCurrent().isSuggestionsEnabledPerUserSettings()) { 301ac6dfaf80bb280cbc9afb2d6e697379b3fd1f373Jean Chalard return; 302ac6dfaf80bb280cbc9afb2d6e697379b3fd1f373Jean Chalard } 3039f9cc032773a528b4eb6e036db0c37ff45385cceJean Chalard removeMessages(MSG_RESUME_SUGGESTIONS); 3049444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard removeMessages(MSG_RESUME_SUGGESTIONS_FOR_START_INPUT); 3059444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard final int message = forStartInput ? MSG_RESUME_SUGGESTIONS_FOR_START_INPUT 3069444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard : MSG_RESUME_SUGGESTIONS; 307fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard if (shouldDelay) { 3089444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard sendMessageDelayed(obtainMessage(message), 3094c90df7e5b916e1d9e48e6902a8d0e884ee44673Jean Chalard mDelayInMillisecondsToUpdateSuggestions); 310fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard } else { 3119444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard sendMessage(obtainMessage(message)); 312fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard } 3136a114fa700d3ca73c608e1291b74bbbdd5a1a7b7Jean Chalard } 3146a114fa700d3ca73c608e1291b74bbbdd5a1a7b7Jean Chalard 3159444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard public void postResumeSuggestions(final boolean shouldDelay) { 3169444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard postResumeSuggestionsInternal(shouldDelay, false /* forStartInput */); 3179444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard } 3189444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard 3199444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard public void postResumeSuggestionsForStartInput(final boolean shouldDelay) { 3209444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard postResumeSuggestionsInternal(shouldDelay, true /* forStartInput */); 3219444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard } 3229444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard 323772a8019efbc280f6228fc2d7baca66f5dee755eJean Chalard public void postResetCaches(final boolean tryResumeSuggestions, final int remainingTries) { 324f1d8aa46f9172c2d8864d0d2161aa8220d036cc9Jean Chalard removeMessages(MSG_RESET_CACHES); 325f1d8aa46f9172c2d8864d0d2161aa8220d036cc9Jean Chalard sendMessage(obtainMessage(MSG_RESET_CACHES, tryResumeSuggestions ? 1 : 0, 326f1d8aa46f9172c2d8864d0d2161aa8220d036cc9Jean Chalard remainingTries, null)); 327f1d8aa46f9172c2d8864d0d2161aa8220d036cc9Jean Chalard } 328f1d8aa46f9172c2d8864d0d2161aa8220d036cc9Jean Chalard 329fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard public void postWaitForDictionaryLoad() { 330fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard sendMessageDelayed(obtainMessage(MSG_WAIT_FOR_DICTIONARY_LOAD), 3317b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu DELAY_WAIT_FOR_DICTIONARY_LOAD_MILLIS); 332fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard } 333fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard 334fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard public void cancelWaitForDictionaryLoad() { 335fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard removeMessages(MSG_WAIT_FOR_DICTIONARY_LOAD); 336fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard } 337fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard 338fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard public boolean hasPendingWaitForDictionaryLoad() { 339fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard return hasMessages(MSG_WAIT_FOR_DICTIONARY_LOAD); 340fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard } 341fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard 342d81e7d24d384a2bb1aeda65d9b423e4b1d23f185Jean Chalard public void cancelUpdateSuggestionStrip() { 343dc1b84d96cf7fc4ee21cf7df8a12bc7913ffd64eJean Chalard removeMessages(MSG_UPDATE_SUGGESTION_STRIP); 344d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 345d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 346d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka public boolean hasPendingUpdateSuggestions() { 347dc1b84d96cf7fc4ee21cf7df8a12bc7913ffd64eJean Chalard return hasMessages(MSG_UPDATE_SUGGESTION_STRIP); 348d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 349d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 350673c727b7a42e2cee2df4415111bfa94a0a2df3bJean Chalard public boolean hasPendingReopenDictionaries() { 351673c727b7a42e2cee2df4415111bfa94a0a2df3bJean Chalard return hasMessages(MSG_REOPEN_DICTIONARIES); 352673c727b7a42e2cee2df4415111bfa94a0a2df3bJean Chalard } 353673c727b7a42e2cee2df4415111bfa94a0a2df3bJean Chalard 354beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka public void postUpdateShiftState() { 355d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka removeMessages(MSG_UPDATE_SHIFT_STATE); 356a61b7245b030395451b4c42ec218a946aa95e030Yohei Yukawa sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE), 357a61b7245b030395451b4c42ec218a946aa95e030Yohei Yukawa mDelayInMillisecondsToUpdateShiftState); 358d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka } 359d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka 3607b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu public void postDeallocateMemory() { 3617b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu sendMessageDelayed(obtainMessage(MSG_DEALLOCATE_MEMORY), 3627b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu DELAY_DEALLOCATE_MEMORY_MILLIS); 3637b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu } 3647b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu 3657b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu public void cancelDeallocateMemory() { 3667b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu removeMessages(MSG_DEALLOCATE_MEMORY); 3677b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu } 3687b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu 3697b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu public boolean hasPendingDeallocateMemory() { 3707b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu return hasMessages(MSG_DEALLOCATE_MEMORY); 3717b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu } 3727b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu 3732fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa @UsedForTesting 3742fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa public void removeAllMessages() { 3752fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa for (int i = 0; i <= MSG_LAST; ++i) { 3762fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa removeMessages(i); 3772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 3782fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 3792fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 380f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void showGesturePreviewAndSuggestionStrip(final SuggestedWords suggestedWords, 381f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka final boolean dismissGestureFloatingPreviewText) { 382f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka removeMessages(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP); 383f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka final int arg1 = dismissGestureFloatingPreviewText 384908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada ? ARG1_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT 385908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada : ARG1_SHOW_GESTURE_FLOATING_PREVIEW_TEXT; 386a469743e331e57e3a03354f95268e4addf93b0e8Yuichiro Hanada obtainMessage(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP, arg1, 387084c9961f4ede347fbfb719ce1075a10b93867c3Jean Chalard ARG2_UNUSED, suggestedWords).sendToTarget(); 388f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka } 389f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka 390908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada public void showSuggestionStrip(final SuggestedWords suggestedWords) { 391908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada removeMessages(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP); 392908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada obtainMessage(MSG_SHOW_GESTURE_PREVIEW_AND_SUGGESTION_STRIP, 393084c9961f4ede347fbfb719ce1075a10b93867c3Jean Chalard ARG1_NOT_GESTURE_INPUT, ARG2_UNUSED, suggestedWords).sendToTarget(); 394908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada } 395908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada 396a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard public void showTailBatchInputResult(final SuggestedWords suggestedWords) { 397a777c1c46073d7dc56590e58bdedb497bdfad182Jean Chalard obtainMessage(MSG_UPDATE_TAIL_BATCH_INPUT_COMPLETED, suggestedWords).sendToTarget(); 398908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada } 399908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada 400809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa public void postSwitchLanguage(final InputMethodSubtype subtype) { 401809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa obtainMessage(MSG_SWITCH_LANGUAGE_AUTOMATICALLY, subtype).sendToTarget(); 402809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa } 403809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa 40459f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka // Working variables for the following methods. 40559f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka private boolean mIsOrientationChanging; 4065fd11a7f3367d51cea8dc83fb9675c93d82a2e4eJean Chalard private boolean mPendingSuccessiveImsCallback; 40759f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka private boolean mHasPendingStartInput; 40859f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka private boolean mHasPendingFinishInputView; 40959f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka private boolean mHasPendingFinishInput; 410e7eac906c0a14b644d457beeb73a407fa1b63673Tadashi G. Takaoka private EditorInfo mAppliedEditorInfo; 41159f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka 41259f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka public void startOrientationChanging() { 413dd25e4fa2c7dd1e32a9e6f5fd21f54214919ef20Tadashi G. Takaoka removeMessages(MSG_PENDING_IMS_CALLBACK); 414dd25e4fa2c7dd1e32a9e6f5fd21f54214919ef20Tadashi G. Takaoka resetPendingImsCallback(); 41559f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka mIsOrientationChanging = true; 4162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final LatinIME latinIme = getOwnerInstance(); 41798534dc065a828525129dc23aaca3ebd8834514cKen Wakasa if (latinIme == null) { 41898534dc065a828525129dc23aaca3ebd8834514cKen Wakasa return; 41998534dc065a828525129dc23aaca3ebd8834514cKen Wakasa } 420f2c9a88887a303f3df8bee60788870946dfa55f7Tadashi G. Takaoka if (latinIme.isInputViewShown()) { 421f2c9a88887a303f3df8bee60788870946dfa55f7Tadashi G. Takaoka latinIme.mKeyboardSwitcher.saveKeyboardState(); 422f2c9a88887a303f3df8bee60788870946dfa55f7Tadashi G. Takaoka } 42359f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka } 42459f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka 42559f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka private void resetPendingImsCallback() { 42659f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka mHasPendingFinishInputView = false; 42759f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka mHasPendingFinishInput = false; 42859f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka mHasPendingStartInput = false; 42959f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka } 43059f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka 431f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka private void executePendingImsCallback(final LatinIME latinIme, final EditorInfo editorInfo, 43259f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka boolean restarting) { 43312ff7da19df29511e489f426f372300a674f756aKen Wakasa if (mHasPendingFinishInputView) { 43459f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka latinIme.onFinishInputViewInternal(mHasPendingFinishInput); 43512ff7da19df29511e489f426f372300a674f756aKen Wakasa } 43612ff7da19df29511e489f426f372300a674f756aKen Wakasa if (mHasPendingFinishInput) { 43759f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka latinIme.onFinishInputInternal(); 43812ff7da19df29511e489f426f372300a674f756aKen Wakasa } 43912ff7da19df29511e489f426f372300a674f756aKen Wakasa if (mHasPendingStartInput) { 440e7eac906c0a14b644d457beeb73a407fa1b63673Tadashi G. Takaoka latinIme.onStartInputInternal(editorInfo, restarting); 44112ff7da19df29511e489f426f372300a674f756aKen Wakasa } 44259f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka resetPendingImsCallback(); 44359f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka } 44459f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka 445f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void onStartInput(final EditorInfo editorInfo, final boolean restarting) { 44659f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka if (hasMessages(MSG_PENDING_IMS_CALLBACK)) { 44759f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka // Typically this is the second onStartInput after orientation changed. 44859f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka mHasPendingStartInput = true; 44959f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka } else { 45059f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka if (mIsOrientationChanging && restarting) { 45159f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka // This is the first onStartInput after orientation changed. 45259f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka mIsOrientationChanging = false; 4535fd11a7f3367d51cea8dc83fb9675c93d82a2e4eJean Chalard mPendingSuccessiveImsCallback = true; 45459f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka } 4552fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final LatinIME latinIme = getOwnerInstance(); 45698534dc065a828525129dc23aaca3ebd8834514cKen Wakasa if (latinIme != null) { 45798534dc065a828525129dc23aaca3ebd8834514cKen Wakasa executePendingImsCallback(latinIme, editorInfo, restarting); 45898534dc065a828525129dc23aaca3ebd8834514cKen Wakasa latinIme.onStartInputInternal(editorInfo, restarting); 45998534dc065a828525129dc23aaca3ebd8834514cKen Wakasa } 460055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka } 461055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka } 462055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka 463f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void onStartInputView(final EditorInfo editorInfo, final boolean restarting) { 4646b7100fecaaaf0e8e42c4d2ccebac165e89e79bfTadashi G. Takaoka if (hasMessages(MSG_PENDING_IMS_CALLBACK) 4656b7100fecaaaf0e8e42c4d2ccebac165e89e79bfTadashi G. Takaoka && KeyboardId.equivalentEditorInfoForKeyboard(editorInfo, mAppliedEditorInfo)) { 466e7eac906c0a14b644d457beeb73a407fa1b63673Tadashi G. Takaoka // Typically this is the second onStartInputView after orientation changed. 467e7eac906c0a14b644d457beeb73a407fa1b63673Tadashi G. Takaoka resetPendingImsCallback(); 468e7eac906c0a14b644d457beeb73a407fa1b63673Tadashi G. Takaoka } else { 4695fd11a7f3367d51cea8dc83fb9675c93d82a2e4eJean Chalard if (mPendingSuccessiveImsCallback) { 470e7eac906c0a14b644d457beeb73a407fa1b63673Tadashi G. Takaoka // This is the first onStartInputView after orientation changed. 4715fd11a7f3367d51cea8dc83fb9675c93d82a2e4eJean Chalard mPendingSuccessiveImsCallback = false; 472e7eac906c0a14b644d457beeb73a407fa1b63673Tadashi G. Takaoka resetPendingImsCallback(); 473e7eac906c0a14b644d457beeb73a407fa1b63673Tadashi G. Takaoka sendMessageDelayed(obtainMessage(MSG_PENDING_IMS_CALLBACK), 4747b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu PENDING_IMS_CALLBACK_DURATION_MILLIS); 475e7eac906c0a14b644d457beeb73a407fa1b63673Tadashi G. Takaoka } 4762fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final LatinIME latinIme = getOwnerInstance(); 47798534dc065a828525129dc23aaca3ebd8834514cKen Wakasa if (latinIme != null) { 47898534dc065a828525129dc23aaca3ebd8834514cKen Wakasa executePendingImsCallback(latinIme, editorInfo, restarting); 47998534dc065a828525129dc23aaca3ebd8834514cKen Wakasa latinIme.onStartInputViewInternal(editorInfo, restarting); 48098534dc065a828525129dc23aaca3ebd8834514cKen Wakasa mAppliedEditorInfo = editorInfo; 48198534dc065a828525129dc23aaca3ebd8834514cKen Wakasa } 4827b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu cancelDeallocateMemory(); 483e7eac906c0a14b644d457beeb73a407fa1b63673Tadashi G. Takaoka } 48459f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka } 48559f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka 486f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void onFinishInputView(final boolean finishingInput) { 48759f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka if (hasMessages(MSG_PENDING_IMS_CALLBACK)) { 48859f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka // Typically this is the first onFinishInputView after orientation changed. 48959f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka mHasPendingFinishInputView = true; 49059f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka } else { 4912fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final LatinIME latinIme = getOwnerInstance(); 49298534dc065a828525129dc23aaca3ebd8834514cKen Wakasa if (latinIme != null) { 49398534dc065a828525129dc23aaca3ebd8834514cKen Wakasa latinIme.onFinishInputViewInternal(finishingInput); 49498534dc065a828525129dc23aaca3ebd8834514cKen Wakasa mAppliedEditorInfo = null; 49598534dc065a828525129dc23aaca3ebd8834514cKen Wakasa } 4967b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu if (!hasPendingDeallocateMemory()) { 4977b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu postDeallocateMemory(); 4987b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu } 49938f55b36c3992a580cf7e20668b1eb72a4eb2431Tadashi G. Takaoka } 50038f55b36c3992a580cf7e20668b1eb72a4eb2431Tadashi G. Takaoka } 501ffd156c77e93a54b704780b46886ba597d1c77cbTadashi G. Takaoka 50259f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka public void onFinishInput() { 50359f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka if (hasMessages(MSG_PENDING_IMS_CALLBACK)) { 50459f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka // Typically this is the first onFinishInput after orientation changed. 50559f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka mHasPendingFinishInput = true; 50659f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka } else { 5072fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final LatinIME latinIme = getOwnerInstance(); 50898534dc065a828525129dc23aaca3ebd8834514cKen Wakasa if (latinIme != null) { 50998534dc065a828525129dc23aaca3ebd8834514cKen Wakasa executePendingImsCallback(latinIme, null, false); 51098534dc065a828525129dc23aaca3ebd8834514cKen Wakasa latinIme.onFinishInputInternal(); 51198534dc065a828525129dc23aaca3ebd8834514cKen Wakasa } 512ffd156c77e93a54b704780b46886ba597d1c77cbTadashi G. Takaoka } 513ffd156c77e93a54b704780b46886ba597d1c77cbTadashi G. Takaoka } 51438f55b36c3992a580cf7e20668b1eb72a4eb2431Tadashi G. Takaoka } 51538f55b36c3992a580cf7e20668b1eb72a4eb2431Tadashi G. Takaoka 5161931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka static final class SubtypeState { 5171931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka private InputMethodSubtype mLastActiveSubtype; 5186345562e2b351221a9bc0341f7dbd26095290b64Jean Chalard private boolean mCurrentSubtypeHasBeenUsed; 5191931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka 5206345562e2b351221a9bc0341f7dbd26095290b64Jean Chalard public void setCurrentSubtypeHasBeenUsed() { 5216345562e2b351221a9bc0341f7dbd26095290b64Jean Chalard mCurrentSubtypeHasBeenUsed = true; 5221931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka } 5231931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka 5241931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka public void switchSubtype(final IBinder token, final RichInputMethodManager richImm) { 5251931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka final InputMethodSubtype currentSubtype = richImm.getInputMethodManager() 5261931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka .getCurrentInputMethodSubtype(); 5271931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka final InputMethodSubtype lastActiveSubtype = mLastActiveSubtype; 5286345562e2b351221a9bc0341f7dbd26095290b64Jean Chalard final boolean currentSubtypeHasBeenUsed = mCurrentSubtypeHasBeenUsed; 5296345562e2b351221a9bc0341f7dbd26095290b64Jean Chalard if (currentSubtypeHasBeenUsed) { 5301931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka mLastActiveSubtype = currentSubtype; 5316345562e2b351221a9bc0341f7dbd26095290b64Jean Chalard mCurrentSubtypeHasBeenUsed = false; 5321931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka } 5336345562e2b351221a9bc0341f7dbd26095290b64Jean Chalard if (currentSubtypeHasBeenUsed 5341931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka && richImm.checkIfSubtypeBelongsToThisImeAndEnabled(lastActiveSubtype) 5351931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka && !currentSubtype.equals(lastActiveSubtype)) { 5361931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka richImm.setInputMethodAndSubtype(token, lastActiveSubtype); 5371931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka return; 5381931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka } 5391931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka richImm.switchToNextInputMethod(token, true /* onlyCurrentIme */); 5401931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka } 5411931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka } 5421931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka 543bfaf349c3554e11af8227a5f0807a74107a93069Ken Wakasa // Loading the native library eagerly to avoid unexpected UnsatisfiedLinkError at the initial 544bfaf349c3554e11af8227a5f0807a74107a93069Ken Wakasa // JNI call as much as possible. 545bfaf349c3554e11af8227a5f0807a74107a93069Ken Wakasa static { 546bfaf349c3554e11af8227a5f0807a74107a93069Ken Wakasa JniUtils.loadNativeLibrary(); 547bfaf349c3554e11af8227a5f0807a74107a93069Ken Wakasa } 548bfaf349c3554e11af8227a5f0807a74107a93069Ken Wakasa 54989ffb212b469531db4a616afb9bb7ba6d2a56b50Jean Chalard public LatinIME() { 55089ffb212b469531db4a616afb9bb7ba6d2a56b50Jean Chalard super(); 551ff0735ada807239abeb4c6105b7d01d2bcea0aedTadashi G. Takaoka mSettings = Settings.getInstance(); 55289ffb212b469531db4a616afb9bb7ba6d2a56b50Jean Chalard mKeyboardSwitcher = KeyboardSwitcher.getInstance(); 553aabb3512791979a00c0ab50c0be808f46d18cbe6Jatin Matani mStatsUtilsManager = StatsUtilsManager.getInstance(); 554fb955693d4bb0c8d39092250a4208e385b8a31a7Ken Wakasa mIsHardwareAcceleratedDrawingEnabled = 555fb955693d4bb0c8d39092250a4208e385b8a31a7Ken Wakasa InputMethodServiceCompatUtils.enableHardwareAcceleration(this); 556fb955693d4bb0c8d39092250a4208e385b8a31a7Ken Wakasa Log.i(TAG, "Hardware accelerated drawing: " + mIsHardwareAcceleratedDrawingEnabled); 55789ffb212b469531db4a616afb9bb7ba6d2a56b50Jean Chalard } 55889ffb212b469531db4a616afb9bb7ba6d2a56b50Jean Chalard 5597e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka @Override 5607e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka public void onCreate() { 561ff0735ada807239abeb4c6105b7d01d2bcea0aedTadashi G. Takaoka Settings.init(this); 5622dae79b1966a7970c25c8b79beec1c95c13f6c87Tadashi G. Takaoka DebugFlags.init(PreferenceManager.getDefaultSharedPreferences(this)); 563f90fc105ab1159f43f536bcacdd1224c2c05bacbTadashi G. Takaoka RichInputMethodManager.init(this); 56485e397cd1060f3878d9a55373b7409641175179aTadashi G. Takaoka mRichImm = RichInputMethodManager.getInstance(); 565f90fc105ab1159f43f536bcacdd1224c2c05bacbTadashi G. Takaoka KeyboardSwitcher.init(this); 566b17b88742528d09eaa36adb3dae5348b99c234e0Tadashi G. Takaoka AudioAndHapticFeedbackManager.init(this); 5672ac5988f84b5c38d313951a3d7faddebf5f25e04Tadashi G. Takaoka AccessibilityUtils.init(this); 5680103d75aaf0472051147b047fc68fe8ae6881de5Chieu Nguyen mStatsUtilsManager.onCreate(this /* context */, mDictionaryFacilitator); 569923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onCreate(); 570363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka 57110dff76856a98b6eec86a53d3d07fdc9708037b7Tadashi G. Takaoka mHandler.onCreate(); 572363cd6ef0f8f8af41a01964a2f0e800f9305d3a2Tadashi G. Takaoka 5731c0876dc49eee44170cb86ba3d78e759d5bbd573Jean Chalard // TODO: Resolve mutual dependencies of {@link #loadSettings()} and 5741c0876dc49eee44170cb86ba3d78e759d5bbd573Jean Chalard // {@link #resetDictionaryFacilitatorIfNecessary()}. 57528f36d68afe8d323d1032d0e03fe3013449e21feKen Wakasa loadSettings(); 5761c0876dc49eee44170cb86ba3d78e759d5bbd573Jean Chalard resetDictionaryFacilitatorIfNecessary(); 577979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 5782b25f674f29a4c7b3c8d70bc0fbfbdc60da131c4Tadashi G. Takaoka // Register to receive ringer mode change. 579123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka final IntentFilter filter = new IntentFilter(); 58021af2f40c59de3ea5ec183aa278406bf28d5e3bdJean Chalard filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); 5812b25f674f29a4c7b3c8d70bc0fbfbdc60da131c4Tadashi G. Takaoka registerReceiver(mRingerModeChangeReceiver, filter); 582cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard 5832b25f674f29a4c7b3c8d70bc0fbfbdc60da131c4Tadashi G. Takaoka // Register to receive installation and removal of a dictionary pack. 584efd26bb3192722c2980098a6f36dff6006e8896aKurt Partridge final IntentFilter packageFilter = new IntentFilter(); 585efd26bb3192722c2980098a6f36dff6006e8896aKurt Partridge packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED); 586efd26bb3192722c2980098a6f36dff6006e8896aKurt Partridge packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 587efd26bb3192722c2980098a6f36dff6006e8896aKurt Partridge packageFilter.addDataScheme(SCHEME_PACKAGE); 588efd26bb3192722c2980098a6f36dff6006e8896aKurt Partridge registerReceiver(mDictionaryPackInstallReceiver, packageFilter); 589efd26bb3192722c2980098a6f36dff6006e8896aKurt Partridge 590efd26bb3192722c2980098a6f36dff6006e8896aKurt Partridge final IntentFilter newDictFilter = new IntentFilter(); 591efd26bb3192722c2980098a6f36dff6006e8896aKurt Partridge newDictFilter.addAction(DictionaryPackConstants.NEW_DICTIONARY_INTENT_ACTION); 592efd26bb3192722c2980098a6f36dff6006e8896aKurt Partridge registerReceiver(mDictionaryPackInstallReceiver, newDictFilter); 593908fc4f1c324eac2a42a69680dbd196c5b9492f6Yuichiro Hanada 59436c7a62dffb7f5b6728fa0850c1f63aee0f14d80Keisuke Kuroyanagi final IntentFilter dictDumpFilter = new IntentFilter(); 59536c7a62dffb7f5b6728fa0850c1f63aee0f14d80Keisuke Kuroyanagi dictDumpFilter.addAction(DictionaryDumpBroadcastReceiver.DICTIONARY_DUMP_INTENT_ACTION); 59636c7a62dffb7f5b6728fa0850c1f63aee0f14d80Keisuke Kuroyanagi registerReceiver(mDictionaryDumpBroadcastReceiver, dictDumpFilter); 59736c7a62dffb7f5b6728fa0850c1f63aee0f14d80Keisuke Kuroyanagi 598698b19ef35d1d865943ec9d9ee05f8f0e66dc3f8Mohammadinamul Sheik StatsUtils.onCreate(mSettings.getCurrent(), mRichImm); 599923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 60036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 60117c7ffeb1e10348227c5dff1c319d2099c1b5d0eJean Chalard // Has to be package-visible for unit tests 60215f6d4ae34664ea3d92827a2c3003198c0bac70bTadashi G. Takaoka @UsedForTesting 6039fc6af325ec91a1a22c0679d374c0c3d6d03d9acTadashi G. Takaoka void loadSettings() { 604107fb4c476779df16be23e245547253978c197acDan Zivkovic final Locale locale = mRichImm.getCurrentSubtypeLocale(); 6051404c1af850236da4fe4ed3825b70cb228a1da5bJean Chalard final EditorInfo editorInfo = getCurrentInputEditorInfo(); 6063ca65c8fd56724a7b4b3440bccf613e5a1a17513Tadashi G. Takaoka final InputAttributes inputAttributes = new InputAttributes( 6073ca65c8fd56724a7b4b3440bccf613e5a1a17513Tadashi G. Takaoka editorInfo, isFullscreenMode(), getPackageName()); 608107fb4c476779df16be23e245547253978c197acDan Zivkovic mSettings.loadSettings(this, locale, inputAttributes); 609f1457e7a221082688b6399853e84e77948633c7bKeisuke Kuroyanagi final SettingsValues currentSettingsValues = mSettings.getCurrent(); 610e9926b0d11d481c6534c059384c9a5a858ebdaaeKeisuke Kuroyanagi AudioAndHapticFeedbackManager.getInstance().onSettingsChanged(currentSettingsValues); 611e9926b0d11d481c6534c059384c9a5a858ebdaaeKeisuke Kuroyanagi // This method is called on startup and language switch, before the new layout has 612e9926b0d11d481c6534c059384c9a5a858ebdaaeKeisuke Kuroyanagi // been displayed. Opening dictionaries never affects responsivity as dictionaries are 613e9926b0d11d481c6534c059384c9a5a858ebdaaeKeisuke Kuroyanagi // asynchronously loaded. 614adfb262797023c4ca57bb470e547f90c88f638caKeisuke Kuroyanagi if (!mHandler.hasPendingReopenDictionaries()) { 615107fb4c476779df16be23e245547253978c197acDan Zivkovic resetDictionaryFacilitator(locale); 616f1457e7a221082688b6399853e84e77948633c7bKeisuke Kuroyanagi } 617d7a22c8439c77f2bf81b5dc60d58cf65d129da81Keisuke Kuroyanagi refreshPersonalizationDictionarySession(currentSettingsValues); 618bc4ae6bdc0249f9282efea5d1fe7ccfefd6f93b0Jatin Matani resetDictionaryFacilitatorIfNecessary(); 6190103d75aaf0472051147b047fc68fe8ae6881de5Chieu Nguyen mStatsUtilsManager.onLoadSettings(this /* context */, currentSettingsValues); 6209f1fe87580adc9ca041fc044f88341fa262c82a2Keisuke Kuroyanagi } 6219f1fe87580adc9ca041fc044f88341fa262c82a2Keisuke Kuroyanagi 622d7a22c8439c77f2bf81b5dc60d58cf65d129da81Keisuke Kuroyanagi private void refreshPersonalizationDictionarySession( 623d7a22c8439c77f2bf81b5dc60d58cf65d129da81Keisuke Kuroyanagi final SettingsValues currentSettingsValues) { 6249a289da4e6ea40417422a540e821069d5d6e4a82Dan Zivkovic if (!currentSettingsValues.mUsePersonalizedDicts) { 625d102eb80da07de6b9541c3e8d767441d84257b8dKeisuke Kuroyanagi // Remove user history dictionaries. 626d102eb80da07de6b9541c3e8d767441d84257b8dKeisuke Kuroyanagi PersonalizationHelper.removeAllUserHistoryDictionaries(this); 627bdd6c995cee664e6cd025235be2d00fc439afb1dDan Zivkovic mDictionaryFacilitator.clearUserHistoryDictionary(this); 628d102eb80da07de6b9541c3e8d767441d84257b8dKeisuke Kuroyanagi } 62917c7ffeb1e10348227c5dff1c319d2099c1b5d0eJean Chalard } 63017c7ffeb1e10348227c5dff1c319d2099c1b5d0eJean Chalard 6318335c59ea7715f3dbc6625f128a7a038f314a89fTadashi G. Takaoka // Note that this method is called from a non-UI thread. 632369e54cc338d8115d63138663b882f56208d7ec3Tadashi G. Takaoka @Override 633f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void onUpdateMainDictionaryAvailability(final boolean isMainDictionaryAvailable) { 6348335c59ea7715f3dbc6625f128a7a038f314a89fTadashi G. Takaoka final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); 6358335c59ea7715f3dbc6625f128a7a038f314a89fTadashi G. Takaoka if (mainKeyboardView != null) { 6368335c59ea7715f3dbc6625f128a7a038f314a89fTadashi G. Takaoka mainKeyboardView.setMainDictionaryAvailability(isMainDictionaryAvailable); 6378335c59ea7715f3dbc6625f128a7a038f314a89fTadashi G. Takaoka } 638fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard if (mHandler.hasPendingWaitForDictionaryLoad()) { 639fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard mHandler.cancelWaitForDictionaryLoad(); 6404c90df7e5b916e1d9e48e6902a8d0e884ee44673Jean Chalard mHandler.postResumeSuggestions(false /* shouldDelay */); 641fa4c59f9b6663e5de08692f853e968603dfc10e9Jean Chalard } 642369e54cc338d8115d63138663b882f56208d7ec3Tadashi G. Takaoka } 643369e54cc338d8115d63138663b882f56208d7ec3Tadashi G. Takaoka 6445f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka void resetDictionaryFacilitatorIfNecessary() { 645107fb4c476779df16be23e245547253978c197acDan Zivkovic final Locale subtypeSwitcherLocale = mRichImm.getCurrentSubtypeLocale(); 646107fb4c476779df16be23e245547253978c197acDan Zivkovic final Locale subtypeLocale; 647107fb4c476779df16be23e245547253978c197acDan Zivkovic if (subtypeSwitcherLocale == null) { 64843a8a0c5270a54742dcfff9dc441cf2747cb4e06Jean Chalard // This happens in very rare corner cases - for example, immediately after a switch 64943a8a0c5270a54742dcfff9dc441cf2747cb4e06Jean Chalard // to LatinIME has been requested, about a frame later another switch happens. In this 65043a8a0c5270a54742dcfff9dc441cf2747cb4e06Jean Chalard // case, we are about to go down but we still don't know it, however the system tells 651bc051a561f1766e5cea2866468c769f5cb346ffbJean Chalard // us there is no current subtype. 65243a8a0c5270a54742dcfff9dc441cf2747cb4e06Jean Chalard Log.e(TAG, "System is reporting no current subtype."); 653107fb4c476779df16be23e245547253978c197acDan Zivkovic subtypeLocale = getResources().getConfiguration().locale; 65443a8a0c5270a54742dcfff9dc441cf2747cb4e06Jean Chalard } else { 655107fb4c476779df16be23e245547253978c197acDan Zivkovic subtypeLocale = subtypeSwitcherLocale; 656107fb4c476779df16be23e245547253978c197acDan Zivkovic } 657107fb4c476779df16be23e245547253978c197acDan Zivkovic if (mDictionaryFacilitator.isForLocale(subtypeLocale) 658107fb4c476779df16be23e245547253978c197acDan Zivkovic && mDictionaryFacilitator.isForAccount(mSettings.getCurrent().mAccount)) { 659107fb4c476779df16be23e245547253978c197acDan Zivkovic return; 66043a8a0c5270a54742dcfff9dc441cf2747cb4e06Jean Chalard } 661107fb4c476779df16be23e245547253978c197acDan Zivkovic resetDictionaryFacilitator(subtypeLocale); 6629f1fe87580adc9ca041fc044f88341fa262c82a2Keisuke Kuroyanagi } 66336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 664adfb262797023c4ca57bb470e547f90c88f638caKeisuke Kuroyanagi /** 665107fb4c476779df16be23e245547253978c197acDan Zivkovic * Reset the facilitator by loading dictionaries for the given locale and 666bc4ae6bdc0249f9282efea5d1fe7ccfefd6f93b0Jatin Matani * the current settings values. 667adfb262797023c4ca57bb470e547f90c88f638caKeisuke Kuroyanagi * 668107fb4c476779df16be23e245547253978c197acDan Zivkovic * @param locale the locale 669adfb262797023c4ca57bb470e547f90c88f638caKeisuke Kuroyanagi */ 670bc4ae6bdc0249f9282efea5d1fe7ccfefd6f93b0Jatin Matani // TODO: make sure the current settings always have the right locales, and read from them. 671107fb4c476779df16be23e245547253978c197acDan Zivkovic private void resetDictionaryFacilitator(final Locale locale) { 672adfb262797023c4ca57bb470e547f90c88f638caKeisuke Kuroyanagi final SettingsValues settingsValues = mSettings.getCurrent(); 673107fb4c476779df16be23e245547253978c197acDan Zivkovic mDictionaryFacilitator.resetDictionaries(this /* context */, locale, 674adfb262797023c4ca57bb470e547f90c88f638caKeisuke Kuroyanagi settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts, 675bc4ae6bdc0249f9282efea5d1fe7ccfefd6f93b0Jatin Matani false /* forceReloadMainDictionary */, 676d6a8adcb044dd8b73a1c96776a835b411a978b46Dan Zivkovic settingsValues.mAccount, "" /* dictNamePrefix */, 677bc4ae6bdc0249f9282efea5d1fe7ccfefd6f93b0Jatin Matani this /* DictionaryInitializationListener */); 678ab661e3ef886a36b02fe094864ae4be6a3260f71Tadashi G. Takaoka if (settingsValues.mAutoCorrectionEnabledPerUserSettings) { 679adfb262797023c4ca57bb470e547f90c88f638caKeisuke Kuroyanagi mInputLogic.mSuggest.setAutoCorrectionThreshold( 680adfb262797023c4ca57bb470e547f90c88f638caKeisuke Kuroyanagi settingsValues.mAutoCorrectionThreshold); 68178ab80844b4f8e0369f4e86b2a02208197f9bd34Tadashi G. Takaoka } 68256577461d63ad3618598ceddfb9a73b797917061Jean Chalard mInputLogic.mSuggest.setPlausibilityThreshold(settingsValues.mPlausibilityThreshold); 6839f1fe87580adc9ca041fc044f88341fa262c82a2Keisuke Kuroyanagi } 6849f1fe87580adc9ca041fc044f88341fa262c82a2Keisuke Kuroyanagi 685adfb262797023c4ca57bb470e547f90c88f638caKeisuke Kuroyanagi /** 686adfb262797023c4ca57bb470e547f90c88f638caKeisuke Kuroyanagi * Reset suggest by loading the main dictionary of the current locale. 687adfb262797023c4ca57bb470e547f90c88f638caKeisuke Kuroyanagi */ 6889f1fe87580adc9ca041fc044f88341fa262c82a2Keisuke Kuroyanagi /* package private */ void resetSuggestMainDict() { 689adfb262797023c4ca57bb470e547f90c88f638caKeisuke Kuroyanagi final SettingsValues settingsValues = mSettings.getCurrent(); 690a1035be6d877cafda95b2761f9697474b79deeb8Keisuke Kuroyanagi mDictionaryFacilitator.resetDictionaries(this /* context */, 691107fb4c476779df16be23e245547253978c197acDan Zivkovic mDictionaryFacilitator.getLocale(), settingsValues.mUseContactsDict, 692bc4ae6bdc0249f9282efea5d1fe7ccfefd6f93b0Jatin Matani settingsValues.mUsePersonalizedDicts, 693bc4ae6bdc0249f9282efea5d1fe7ccfefd6f93b0Jatin Matani true /* forceReloadMainDictionary */, 694d6a8adcb044dd8b73a1c96776a835b411a978b46Dan Zivkovic settingsValues.mAccount, "" /* dictNamePrefix */, 695bc4ae6bdc0249f9282efea5d1fe7ccfefd6f93b0Jatin Matani this /* DictionaryInitializationListener */); 696cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard } 697cba93f50c3d46ada773ec49435689dc3e2094385Jean Chalard 698466741d8a78965b8509bf527344f289e50873092Mike LeBeau @Override 699466741d8a78965b8509bf527344f289e50873092Mike LeBeau public void onDestroy() { 700a1035be6d877cafda95b2761f9697474b79deeb8Keisuke Kuroyanagi mDictionaryFacilitator.closeDictionaries(); 701ff0735ada807239abeb4c6105b7d01d2bcea0aedTadashi G. Takaoka mSettings.onDestroy(); 7022b25f674f29a4c7b3c8d70bc0fbfbdc60da131c4Tadashi G. Takaoka unregisterReceiver(mRingerModeChangeReceiver); 703efd26bb3192722c2980098a6f36dff6006e8896aKurt Partridge unregisterReceiver(mDictionaryPackInstallReceiver); 704f2d15d6956c06543fc4c09591a35d35f823f8f0dKeisuke Kuroyanagi unregisterReceiver(mDictionaryDumpBroadcastReceiver); 7052b69244555af209b52181777cdd751cbb543bd93Jatin Matani mStatsUtilsManager.onDestroy(this /* context */); 706923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onDestroy(); 707923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 708923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 7094370ff0998d3240cfda7745d08edbdd11703b984Jean Chalard @UsedForTesting 7104370ff0998d3240cfda7745d08edbdd11703b984Jean Chalard public void recycle() { 71166e509b1d4a8f41a7e4d6e26dfa0dd9995e945a9Jean Chalard unregisterReceiver(mDictionaryPackInstallReceiver); 71266e509b1d4a8f41a7e4d6e26dfa0dd9995e945a9Jean Chalard unregisterReceiver(mDictionaryDumpBroadcastReceiver); 7132b25f674f29a4c7b3c8d70bc0fbfbdc60da131c4Tadashi G. Takaoka unregisterReceiver(mRingerModeChangeReceiver); 7144370ff0998d3240cfda7745d08edbdd11703b984Jean Chalard mInputLogic.recycle(); 7154370ff0998d3240cfda7745d08edbdd11703b984Jean Chalard } 7164370ff0998d3240cfda7745d08edbdd11703b984Jean Chalard 7171fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic private boolean isImeSuppressedByHardwareKeyboard() { 7181fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic final KeyboardSwitcher switcher = KeyboardSwitcher.getInstance(); 71948adccf34910e694b8751b8dfdb76b3c7281c1e8Keisuke Kuroyanagi return !onEvaluateInputViewShown() && switcher.isImeSuppressedByHardwareKeyboard( 7201fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic mSettings.getCurrent(), switcher.getKeyboardSwitchState()); 7211fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic } 7221fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic 723923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 724f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void onConfigurationChanged(final Configuration conf) { 7259395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard SettingsValues settingsValues = mSettings.getCurrent(); 726aa161eb371d8042ef4c1f9207648b3aeacb65e4eJean Chalard if (settingsValues.mDisplayOrientation != conf.orientation) { 727f94df382fb3f73c03cfef5f0a28856bf3f1c73daTadashi G. Takaoka mHandler.startOrientationChanging(); 72828ebbd481ad38f41211d853bf5eb39b36842be36Jean Chalard mInputLogic.onOrientationChange(mSettings.getCurrent()); 729b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani } 7309395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard if (settingsValues.mHasHardwareKeyboard != Settings.readHasHardwareKeyboard(conf)) { 7319395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // If the state of having a hardware keyboard changed, then we want to reload the 7329395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // settings to adjust for that. 7339395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // TODO: we should probably do this unconditionally here, rather than only when we 7349395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // have a change in hardware keyboard configuration. 7359395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard loadSettings(); 7369395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard settingsValues = mSettings.getCurrent(); 7371fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic if (isImeSuppressedByHardwareKeyboard()) { 7389395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // We call cleanupInternalStateForFinishInput() because it's the right thing to do; 7399395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // however, it seems at the moment the framework is passing us a seemingly valid 7409395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // but actually non-functional InputConnection object. So if this bug ever gets 7419395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // fixed we'll be able to remove the composition, but until it is this code is 7429395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // actually not doing much. 7439395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard cleanupInternalStateForFinishInput(); 7449395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard } 7459395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard } 746923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onConfigurationChanged(conf); 747923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 748b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani 749923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 750923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public View onCreateInputView() { 7511c45f9142bb2cf79aa7da29bc01f11195678aadaJatin Matani StatsUtils.onCreateInputView(); 752622d6a5b1b3d6a9140765b868abf1cdf412bc4f3Tadashi G. Takaoka return mKeyboardSwitcher.onCreateInputView(mIsHardwareAcceleratedDrawingEnabled); 7536c4add55f94ff729ef1aa35c4f8df3b086344f8aTadashi G. Takaoka } 7546c4add55f94ff729ef1aa35c4f8df3b086344f8aTadashi G. Takaoka 7556c4add55f94ff729ef1aa35c4f8df3b086344f8aTadashi G. Takaoka @Override 756c160a3932f74fea72c5347798c001d4ae961864cKen Wakasa public void setInputView(final View view) { 757c160a3932f74fea72c5347798c001d4ae961864cKen Wakasa super.setInputView(view); 7588fdff5a11129827e88ce9f5bc462e18f613c19a3Tadashi G. Takaoka mInputView = view; 75915480481be790c913b0117d0841565efd399cd01Tadashi G. Takaoka mInsetsUpdater = ViewOutlineProviderCompatUtils.setInsetsOutlineProvider(view); 76096d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka updateSoftInputWindowLayoutParameters(); 761c160a3932f74fea72c5347798c001d4ae961864cKen Wakasa mSuggestionStripView = (SuggestionStripView)view.findViewById(R.id.suggestion_strip_view); 76212ff7da19df29511e489f426f372300a674f756aKen Wakasa if (hasSuggestionStripView()) { 763c160a3932f74fea72c5347798c001d4ae961864cKen Wakasa mSuggestionStripView.setListener(this, view); 7642fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 765923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 766923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 767923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 768f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void setCandidatesView(final View view) { 769c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka // To ensure that CandidatesView will never be set. 770923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 771923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 772a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker @Override 773f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void onStartInput(final EditorInfo editorInfo, final boolean restarting) { 774e7eac906c0a14b644d457beeb73a407fa1b63673Tadashi G. Takaoka mHandler.onStartInput(editorInfo, restarting); 77559f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka } 77659f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka 77759f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka @Override 778f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void onStartInputView(final EditorInfo editorInfo, final boolean restarting) { 779e7eac906c0a14b644d457beeb73a407fa1b63673Tadashi G. Takaoka mHandler.onStartInputView(editorInfo, restarting); 7806a6137325b82d3dc6ca09e7d918ea50e50c9ac03Jatin Matani mStatsUtilsManager.onStartInputView(); 78159f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka } 78259f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka 78359f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka @Override 784f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void onFinishInputView(final boolean finishingInput) { 7851c45f9142bb2cf79aa7da29bc01f11195678aadaJatin Matani StatsUtils.onFinishInputView(); 78659f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka mHandler.onFinishInputView(finishingInput); 7876a6137325b82d3dc6ca09e7d918ea50e50c9ac03Jatin Matani mStatsUtilsManager.onFinishInputView(); 788c92c883fdf2287b49392692fa2e8d109dc26f785David Faden mGestureConsumer = GestureConsumer.NULL_GESTURE_CONSUMER; 78959f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka } 79038f55b36c3992a580cf7e20668b1eb72a4eb2431Tadashi G. Takaoka 79159f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka @Override 79259f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka public void onFinishInput() { 79359f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka mHandler.onFinishInput(); 79459f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka } 79559f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka 7969cc2c94c8b4bfd4e00e5d3478b9f6e520e791bc5Tadashi G. Takaoka @Override 797f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void onCurrentInputMethodSubtypeChanged(final InputMethodSubtype subtype) { 7984f96bb4520de3610ae94da96b98e507ca7b76362satok // Note that the calling sequence of onCreate() and onCurrentInputMethodSubtypeChanged() 7994f96bb4520de3610ae94da96b98e507ca7b76362satok // is not guaranteed. It may even be called at the same time on a different thread. 80040833d2dd79b193efd33036417ad1909273d9f7dChieu Nguyen InputMethodSubtype oldSubtype = mRichImm.getCurrentSubtype().getRawSubtype(); 80140833d2dd79b193efd33036417ad1909273d9f7dChieu Nguyen StatsUtils.onSubtypeChanged(oldSubtype, subtype); 8024486314225c4bbb97f35cdbdbb2da1de4fc28be2Tadashi G. Takaoka mRichImm.onSubtypeChanged(subtype); 80329200b0abe1d65aa2f9ddefd247ab91563d666f8Yohei Yukawa mInputLogic.onSubtypeChanged(SubtypeLocaleUtils.getCombiningRulesExtraValue(subtype), 80429200b0abe1d65aa2f9ddefd247ab91563d666f8Yohei Yukawa mSettings.getCurrent()); 8059fc6af325ec91a1a22c0679d374c0c3d6d03d9acTadashi G. Takaoka loadKeyboard(); 8069cc2c94c8b4bfd4e00e5d3478b9f6e520e791bc5Tadashi G. Takaoka } 8079cc2c94c8b4bfd4e00e5d3478b9f6e520e791bc5Tadashi G. Takaoka 8085f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka void onStartInputInternal(final EditorInfo editorInfo, final boolean restarting) { 809e7eac906c0a14b644d457beeb73a407fa1b63673Tadashi G. Takaoka super.onStartInput(editorInfo, restarting); 810809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa 811809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa // If the primary hint language does not match the current subtype language, then try 812809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa // to switch to the primary hint language. 813809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa // TODO: Support all the locales in EditorInfo#hintLocales. 814809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa final Locale primaryHintLocale = EditorInfoCompatUtils.getPrimaryHintLocale(editorInfo); 815809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa if (primaryHintLocale == null) { 816809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa return; 817809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa } 818809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa final InputMethodSubtype newSubtype = mRichImm.findSubtypeByLocale(primaryHintLocale); 819809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa if (newSubtype == null || newSubtype.equals(mRichImm.getCurrentSubtype().getRawSubtype())) { 820809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa return; 821809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa } 822809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa mHandler.postSwitchLanguage(newSubtype); 82359f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka } 82459f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka 8251cb08acaf3b4d58cbf4cb65f9fc3990b39e33f00Tadashi G. Takaoka @SuppressWarnings("deprecation") 8265f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka void onStartInputViewInternal(final EditorInfo editorInfo, final boolean restarting) { 827e7eac906c0a14b644d457beeb73a407fa1b63673Tadashi G. Takaoka super.onStartInputView(editorInfo, restarting); 828755b3d882f9d74ceaec7b59fe618dff3ad54f304Dan Zivkovic 829755b3d882f9d74ceaec7b59fe618dff3ad54f304Dan Zivkovic mDictionaryFacilitator.onStartInput(); 830c92c883fdf2287b49392692fa2e8d109dc26f785David Faden // Switch to the null consumer to handle cases leading to early exit below, for which we 831c92c883fdf2287b49392692fa2e8d109dc26f785David Faden // also wouldn't be consuming gesture data. 832c92c883fdf2287b49392692fa2e8d109dc26f785David Faden mGestureConsumer = GestureConsumer.NULL_GESTURE_CONSUMER; 8334486314225c4bbb97f35cdbdbb2da1de4fc28be2Tadashi G. Takaoka mRichImm.refreshSubtypeCaches(); 83445911256fd4e32880e33c42259b19e8d7af70cb1Tadashi G. Takaoka final KeyboardSwitcher switcher = mKeyboardSwitcher; 835db86a6f271e5ca446382061f219928c5eb6b9f01Tadashi G. Takaoka switcher.updateKeyboardTheme(); 83627e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka final MainKeyboardView mainKeyboardView = switcher.getMainKeyboardView(); 8371f3d89c2af645a85d863083ff7956a5ca7e1abc7Jean Chalard // If we are starting input in a different text field from before, we'll have to reload 8381f3d89c2af645a85d863083ff7956a5ca7e1abc7Jean Chalard // settings, so currentSettingsValues can't be final. 8391f3d89c2af645a85d863083ff7956a5ca7e1abc7Jean Chalard SettingsValues currentSettingsValues = mSettings.getCurrent(); 8408e09172df1bb176cc899940862c56bed9b9aec4esatok 841ca7ec2097ca6af1505c1e6aa8b81b6068ba46daesatok if (editorInfo == null) { 842ca7ec2097ca6af1505c1e6aa8b81b6068ba46daesatok Log.e(TAG, "Null EditorInfo in onStartInputView()"); 8432dae79b1966a7970c25c8b79beec1c95c13f6c87Tadashi G. Takaoka if (DebugFlags.DEBUG_ENABLED) { 844ca7ec2097ca6af1505c1e6aa8b81b6068ba46daesatok throw new NullPointerException("Null EditorInfo in onStartInputView()"); 845ca7ec2097ca6af1505c1e6aa8b81b6068ba46daesatok } 846ca7ec2097ca6af1505c1e6aa8b81b6068ba46daesatok return; 847ca7ec2097ca6af1505c1e6aa8b81b6068ba46daesatok } 848edaa83bb32e7299b5bba2c42d703701c1e2a3d5bDan Zivkovic if (DebugFlags.DEBUG_ENABLED) { 849ca7ec2097ca6af1505c1e6aa8b81b6068ba46daesatok Log.d(TAG, "onStartInputView: editorInfo:" 850ca7ec2097ca6af1505c1e6aa8b81b6068ba46daesatok + String.format("inputType=0x%08x imeOptions=0x%08x", 851ca7ec2097ca6af1505c1e6aa8b81b6068ba46daesatok editorInfo.inputType, editorInfo.imeOptions)); 852b6fb5eb391987f3e426649a892cdcbf781957f5asatok Log.d(TAG, "All caps = " 853b6fb5eb391987f3e426649a892cdcbf781957f5asatok + ((editorInfo.inputType & InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS) != 0) 854b6fb5eb391987f3e426649a892cdcbf781957f5asatok + ", sentence caps = " 855b6fb5eb391987f3e426649a892cdcbf781957f5asatok + ((editorInfo.inputType & InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) != 0) 856b6fb5eb391987f3e426649a892cdcbf781957f5asatok + ", word caps = " 857b6fb5eb391987f3e426649a892cdcbf781957f5asatok + ((editorInfo.inputType & InputType.TYPE_TEXT_FLAG_CAP_WORDS) != 0)); 858910b73127fa207dd26ec8124000262523b0aac0csatok } 8593b4c1d30565c06a7f5a4c362002862e8bcb61f01Jean Chalard Log.i(TAG, "Starting input. Cursor position = " 8603b4c1d30565c06a7f5a4c362002862e8bcb61f01Jean Chalard + editorInfo.initialSelStart + "," + editorInfo.initialSelEnd); 861aa4b2c71270576f25e7c80a4b63a1956cec5f4e2Tadashi G. Takaoka // TODO: Consolidate these checks with {@link InputAttributes}. 8621cb08acaf3b4d58cbf4cb65f9fc3990b39e33f00Tadashi G. Takaoka if (InputAttributes.inPrivateImeOptions(null, NO_MICROPHONE_COMPAT, editorInfo)) { 86312ff7da19df29511e489f426f372300a674f756aKen Wakasa Log.w(TAG, "Deprecated private IME option specified: " + editorInfo.privateImeOptions); 8641cb08acaf3b4d58cbf4cb65f9fc3990b39e33f00Tadashi G. Takaoka Log.w(TAG, "Use " + getPackageName() + "." + NO_MICROPHONE + " instead"); 8654f5c3a2898315ff41cc735a195cfeb2937f22f70Tadashi G. Takaoka } 8661cb08acaf3b4d58cbf4cb65f9fc3990b39e33f00Tadashi G. Takaoka if (InputAttributes.inPrivateImeOptions(getPackageName(), FORCE_ASCII, editorInfo)) { 86712ff7da19df29511e489f426f372300a674f756aKen Wakasa Log.w(TAG, "Deprecated private IME option specified: " + editorInfo.privateImeOptions); 8684f5c3a2898315ff41cc735a195cfeb2937f22f70Tadashi G. Takaoka Log.w(TAG, "Use EditorInfo.IME_FLAG_FORCE_ASCII flag instead"); 8694f5c3a2898315ff41cc735a195cfeb2937f22f70Tadashi G. Takaoka } 8704f5c3a2898315ff41cc735a195cfeb2937f22f70Tadashi G. Takaoka 871923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project // In landscape mode, this method gets called without the input view being created. 87227e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka if (mainKeyboardView == null) { 873923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project return; 874923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 875923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 876c92c883fdf2287b49392692fa2e8d109dc26f785David Faden // Update to a gesture consumer with the current editor and IME state. 877c92c883fdf2287b49392692fa2e8d109dc26f785David Faden mGestureConsumer = GestureConsumer.newInstance(editorInfo, 878c92c883fdf2287b49392692fa2e8d109dc26f785David Faden mInputLogic.getPrivateCommandPerformer(), 879107fb4c476779df16be23e245547253978c197acDan Zivkovic mRichImm.getCurrentSubtypeLocale(), 880c92c883fdf2287b49392692fa2e8d109dc26f785David Faden switcher.getKeyboard()); 881c92c883fdf2287b49392692fa2e8d109dc26f785David Faden 882b0c8db018d53b103dcb4b699be27a4e1a2c2f92cAlan Viverette // Forward this event to the accessibility utilities, if enabled. 883b0c8db018d53b103dcb4b699be27a4e1a2c2f92cAlan Viverette final AccessibilityUtils accessUtils = AccessibilityUtils.getInstance(); 884b0c8db018d53b103dcb4b699be27a4e1a2c2f92cAlan Viverette if (accessUtils.isTouchExplorationEnabled()) { 88505384933097c1e9c35e8be5c03757d072e5ffa46alanv accessUtils.onStartInputViewInternal(mainKeyboardView, editorInfo, restarting); 886b0c8db018d53b103dcb4b699be27a4e1a2c2f92cAlan Viverette } 887b0c8db018d53b103dcb4b699be27a4e1a2c2f92cAlan Viverette 8881f3d89c2af645a85d863083ff7956a5ca7e1abc7Jean Chalard final boolean inputTypeChanged = !currentSettingsValues.isSameInputType(editorInfo); 889e234aed4288efd7b4336f3755a958c25a1540b98Jean Chalard final boolean isDifferentTextField = !restarting || inputTypeChanged; 8901c45f9142bb2cf79aa7da29bc01f11195678aadaJatin Matani 8911c45f9142bb2cf79aa7da29bc01f11195678aadaJatin Matani StatsUtils.onStartInputView(editorInfo.inputType, 8921c45f9142bb2cf79aa7da29bc01f11195678aadaJatin Matani Settings.getInstance().getCurrent().mDisplayOrientation, 8931c45f9142bb2cf79aa7da29bc01f11195678aadaJatin Matani !isDifferentTextField); 8941c45f9142bb2cf79aa7da29bc01f11195678aadaJatin Matani 895b2b1eb5ca5a52648eea70920b9bd745b07d3ddfaTadashi G. Takaoka // The EditorInfo might have a flag that affects fullscreen mode. 896b2b1eb5ca5a52648eea70920b9bd745b07d3ddfaTadashi G. Takaoka // Note: This call should be done by InputMethodService? 897b2b1eb5ca5a52648eea70920b9bd745b07d3ddfaTadashi G. Takaoka updateFullscreenMode(); 898c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 8999395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // ALERT: settings have not been reloaded and there is a chance they may be stale. 9009395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // In the practice, if it is, we should have gotten onConfigurationChanged so it should 9019395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // be fine, but this is horribly confusing and must be fixed AS SOON AS POSSIBLE. 902772a8019efbc280f6228fc2d7baca66f5dee755eJean Chalard 9039395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // In some cases the input connection has not been reset yet and we can't access it. In 9049395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // this case we will need to call loadKeyboard() later, when it's accessible, so that we 9059395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // can go into the correct mode, so we need to do some housekeeping here. 9069395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard final boolean needToCallLoadKeyboardLater; 907772a8019efbc280f6228fc2d7baca66f5dee755eJean Chalard final Suggest suggest = mInputLogic.mSuggest; 9081fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic if (!isImeSuppressedByHardwareKeyboard()) { 9099395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // The app calling setText() has the effect of clearing the composing 9109395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // span, so we should reset our state unconditionally, even if restarting is true. 9119395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // We also tell the input logic about the combining rules for the current subtype, so 9129395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // it can adjust its combiners if needed. 9137fb0ed58edd4cc2514f0b5dd5bd2083889ff325cTadashi G. Takaoka mInputLogic.startInput(mRichImm.getCombiningRulesExtraValueOfCurrentSubtype(), 9149395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard currentSettingsValues); 9159395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard 9161c0876dc49eee44170cb86ba3d78e759d5bbd573Jean Chalard resetDictionaryFacilitatorIfNecessary(); 9179395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard 9189395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // TODO[IL]: Can the following be moved to InputLogic#startInput? 9199395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard if (!mInputLogic.mConnection.resetCachesUponCursorMoveAndReturnSuccess( 9209395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard editorInfo.initialSelStart, editorInfo.initialSelEnd, 9219395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard false /* shouldFinishComposition */)) { 9229395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // Sometimes, while rotating, for some reason the framework tells the app we are not 9239395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // connected to it and that means we can't refresh the cache. In this case, schedule 9249395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // a refresh later. 9259395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // We try resetting the caches up to 5 times before giving up. 9269395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard mHandler.postResetCaches(isDifferentTextField, 5 /* remainingTries */); 9279395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // mLastSelection{Start,End} are reset later in this method, no need to do it here 9289395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard needToCallLoadKeyboardLater = true; 9299395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard } else { 93038144047ea3985c9345e7fbe6bb3aafbeaea5f06Jean Chalard // When rotating, and when input is starting again in a field from where the focus 93138144047ea3985c9345e7fbe6bb3aafbeaea5f06Jean Chalard // didn't move (the keyboard having been closed with the back key), 93238144047ea3985c9345e7fbe6bb3aafbeaea5f06Jean Chalard // initialSelStart and initialSelEnd sometimes are lying. Make a best effort to 93338144047ea3985c9345e7fbe6bb3aafbeaea5f06Jean Chalard // work around this bug. 9349395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard mInputLogic.mConnection.tryFixLyingCursorPosition(); 9359444d70514cfa11e88380e653bea3b4a6c205151Jean Chalard mHandler.postResumeSuggestionsForStartInput(true /* shouldDelay */); 9369395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard needToCallLoadKeyboardLater = false; 9379395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard } 938772a8019efbc280f6228fc2d7baca66f5dee755eJean Chalard } else { 9399395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // If we have a hardware keyboard we don't need to call loadKeyboard later anyway. 9409395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard needToCallLoadKeyboardLater = false; 941772a8019efbc280f6228fc2d7baca66f5dee755eJean Chalard } 942772a8019efbc280f6228fc2d7baca66f5dee755eJean Chalard 9431f3d89c2af645a85d863083ff7956a5ca7e1abc7Jean Chalard if (isDifferentTextField || 9441f3d89c2af645a85d863083ff7956a5ca7e1abc7Jean Chalard !currentSettingsValues.hasSameOrientation(getResources().getConfiguration())) { 945772a8019efbc280f6228fc2d7baca66f5dee755eJean Chalard loadSettings(); 946772a8019efbc280f6228fc2d7baca66f5dee755eJean Chalard } 947e234aed4288efd7b4336f3755a958c25a1540b98Jean Chalard if (isDifferentTextField) { 94827e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka mainKeyboardView.closing(); 9491f3d89c2af645a85d863083ff7956a5ca7e1abc7Jean Chalard currentSettingsValues = mSettings.getCurrent(); 95074bcc911ea477415edc19eca829dbba9ab1b2464Jean Chalard 951772a8019efbc280f6228fc2d7baca66f5dee755eJean Chalard if (currentSettingsValues.mAutoCorrectionEnabledPerUserSettings) { 952772a8019efbc280f6228fc2d7baca66f5dee755eJean Chalard suggest.setAutoCorrectionThreshold( 953772a8019efbc280f6228fc2d7baca66f5dee755eJean Chalard currentSettingsValues.mAutoCorrectionThreshold); 954772a8019efbc280f6228fc2d7baca66f5dee755eJean Chalard } 95556577461d63ad3618598ceddfb9a73b797917061Jean Chalard suggest.setPlausibilityThreshold(currentSettingsValues.mPlausibilityThreshold); 956772a8019efbc280f6228fc2d7baca66f5dee755eJean Chalard 957f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard switcher.loadKeyboard(editorInfo, currentSettingsValues, getCurrentAutoCapsState(), 958f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard getCurrentRecapitalizeState()); 9599395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard if (needToCallLoadKeyboardLater) { 9609395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // If we need to call loadKeyboard again later, we need to save its state now. The 9619395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard // later call will be done in #retryResetCaches. 962482aa129e4fa104708601672c9eff674d0a79cd4Jean Chalard switcher.saveKeyboardState(); 9633c4e8cb693ce584ea1f87e354430c069cdd3da39Jean Chalard } 9645d2556b93286f5f1d7d829b586b84a8b7ae55743Ken Wakasa } else if (restarting) { 9655d2556b93286f5f1d7d829b586b84a8b7ae55743Ken Wakasa // TODO: Come up with a more comprehensive way to reset the keyboard layout when 9665d2556b93286f5f1d7d829b586b84a8b7ae55743Ken Wakasa // a keyboard layout set doesn't get reloaded in this method. 967f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard switcher.resetKeyboardStateToAlphabet(getCurrentAutoCapsState(), 968f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard getCurrentRecapitalizeState()); 969d0725a68421203ae42d78ceed57767a5204e858eTadashi G. Takaoka // In apps like Talk, we come here when the text is sent and the field gets emptied and 970d0725a68421203ae42d78ceed57767a5204e858eTadashi G. Takaoka // we need to re-evaluate the shift state, but not the whole layout which would be 971d0725a68421203ae42d78ceed57767a5204e858eTadashi G. Takaoka // disruptive. 972d0725a68421203ae42d78ceed57767a5204e858eTadashi G. Takaoka // Space state must be updated before calling updateShiftState 9738ab4ae4377fca97cb9ef05c615c5a59bc4bc3d8cJean Chalard switcher.requestUpdatingShiftState(getCurrentAutoCapsState(), 9748ab4ae4377fca97cb9ef05c615c5a59bc4bc3d8cJean Chalard getCurrentRecapitalizeState()); 975aa906c36aa31f51a38083e337f4307b49f133054Jean Chalard } 976affdd364232549d2062fc180f924f5b6496c26fdTadashi G. Takaoka // This will set the punctuation suggestions if next word suggestion is off; 977affdd364232549d2062fc180f924f5b6496c26fdTadashi G. Takaoka // otherwise it will clear the suggestion strip. 978145e8568f444bf4b102b2da73e0be8a2b04b50a1Jean Chalard setNeutralSuggestionStrip(); 9798e36e5102e9ac294a0e64ca14920d38ba19e6eb3Jean Chalard 9808e36e5102e9ac294a0e64ca14920d38ba19e6eb3Jean Chalard mHandler.cancelUpdateSuggestionStrip(); 981c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 982adfb262797023c4ca57bb470e547f90c88f638caKeisuke Kuroyanagi mainKeyboardView.setMainDictionaryAvailability( 9838cd53266229895a3e0c6618e3765d57fc5d0b392Jean Chalard mDictionaryFacilitator.hasAtLeastOneInitializedMainDictionary()); 984b60e65a0cce9f20ee5e633921732785f99fffd2eKen Wakasa mainKeyboardView.setKeyPreviewPopupEnabled(currentSettingsValues.mKeyPreviewPopupOn, 985b60e65a0cce9f20ee5e633921732785f99fffd2eKen Wakasa currentSettingsValues.mKeyPreviewPopupDismissDelay); 986ff961ddf8c58df569c97684bfd83a01b2a9470aaTadashi G. Takaoka mainKeyboardView.setSlidingKeyInputPreviewEnabled( 987b60e65a0cce9f20ee5e633921732785f99fffd2eKen Wakasa currentSettingsValues.mSlidingKeyInputPreviewEnabled); 988ff0735ada807239abeb4c6105b7d01d2bcea0aedTadashi G. Takaoka mainKeyboardView.setGestureHandlingEnabledByUser( 989724db044957eb3544323c9814cbb4f20e81b8594Ken Wakasa currentSettingsValues.mGestureInputEnabled, 990724db044957eb3544323c9814cbb4f20e81b8594Ken Wakasa currentSettingsValues.mGestureTrailEnabled, 991b60e65a0cce9f20ee5e633921732785f99fffd2eKen Wakasa currentSettingsValues.mGestureFloatingPreviewTextEnabled); 992c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 993c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); 994c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka } 995c1c4ee6b3a8c3ec42edefe42fd183f3cbf67b0bfTadashi G. Takaoka 996923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 9976c04339c5aadb5118b0e0a8178b3d569956bbad7Seigo Nonaka public void onWindowShown() { 9986c04339c5aadb5118b0e0a8178b3d569956bbad7Seigo Nonaka super.onWindowShown(); 9996c04339c5aadb5118b0e0a8178b3d569956bbad7Seigo Nonaka setNavigationBarVisibility(isInputViewShown()); 10006c04339c5aadb5118b0e0a8178b3d569956bbad7Seigo Nonaka } 10016c04339c5aadb5118b0e0a8178b3d569956bbad7Seigo Nonaka 10026c04339c5aadb5118b0e0a8178b3d569956bbad7Seigo Nonaka @Override 1003e896d31bb92146379c8b7c0050ee05eec0830317Tadashi G. Takaoka public void onWindowHidden() { 1004e896d31bb92146379c8b7c0050ee05eec0830317Tadashi G. Takaoka super.onWindowHidden(); 1005f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); 100627e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka if (mainKeyboardView != null) { 100727e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka mainKeyboardView.closing(); 100827e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka } 10096c04339c5aadb5118b0e0a8178b3d569956bbad7Seigo Nonaka setNavigationBarVisibility(false); 1010e896d31bb92146379c8b7c0050ee05eec0830317Tadashi G. Takaoka } 1011e896d31bb92146379c8b7c0050ee05eec0830317Tadashi G. Takaoka 10125f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka void onFinishInputInternal() { 1013923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onFinishInput(); 1014a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 10159bad1ac33f65dc3454a689b88560988b77a00a87Dan Zivkovic mDictionaryFacilitator.onFinishInput(this); 1016f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); 101727e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka if (mainKeyboardView != null) { 101827e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka mainKeyboardView.closing(); 101927e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka } 1020466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1021466741d8a78965b8509bf527344f289e50873092Mike LeBeau 10225f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka void onFinishInputViewInternal(final boolean finishingInput) { 10236495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa super.onFinishInputView(finishingInput); 10249395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard cleanupInternalStateForFinishInput(); 10259395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard } 10269395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard 10279395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard private void cleanupInternalStateForFinishInput() { 1028d7641636db8fe91d9847ac79f5f431963e876ec3Tadashi G. Takaoka // Remove pending messages related to update suggestions 1029d81e7d24d384a2bb1aeda65d9b423e4b1d23f185Jean Chalard mHandler.cancelUpdateSuggestionStrip(); 1030ff6445ed0eac57f9daf573178ffe9f4e1e2b246aJean Chalard // Should do the following in onFinishInputInternal but until JB MR2 it's not called :( 103181e0ca5fd395fd67c7b93e7d87e7d90fa136f065Jean Chalard mInputLogic.finishInput(); 10326495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa } 10336495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa 10347b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu protected void deallocateMemory() { 10357b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu mKeyboardSwitcher.deallocateMemory(); 10367b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu } 10377b8f3170504ab3f1b4f8eda02ed6f8fb43bdd5cfAdrian Velicu 10386495bfc7a6f6bfa6ab82e7f062ee80f4b6b33368Ken Wakasa @Override 1039f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void onUpdateSelection(final int oldSelStart, final int oldSelEnd, 1040f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka final int newSelStart, final int newSelEnd, 1041f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka final int composingSpanStart, final int composingSpanEnd) { 1042923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, 1043104453908064dcdbb4f10aa4150f1d79beafb408Jean Chalard composingSpanStart, composingSpanEnd); 1044edaa83bb32e7299b5bba2c42d703701c1e2a3d5bDan Zivkovic if (DebugFlags.DEBUG_ENABLED) { 104512ff7da19df29511e489f426f372300a674f756aKen Wakasa Log.i(TAG, "onUpdateSelection: oss=" + oldSelStart + ", ose=" + oldSelEnd 104612ff7da19df29511e489f426f372300a674f756aKen Wakasa + ", nss=" + newSelStart + ", nse=" + newSelEnd 104712ff7da19df29511e489f426f372300a674f756aKen Wakasa + ", cs=" + composingSpanStart + ", ce=" + composingSpanEnd); 1048466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1049466741d8a78965b8509bf527344f289e50873092Mike LeBeau 1050ab68143ad0fb784db38a3fd65612632fca90c789Jean Chalard // This call happens whether our view is displayed or not, but if it's not then we should 1051ab68143ad0fb784db38a3fd65612632fca90c789Jean Chalard // not attempt recorrection. This is true even with a hardware keyboard connected: if the 1052ab68143ad0fb784db38a3fd65612632fca90c789Jean Chalard // view is not displayed we have no means of showing suggestions anyway, and if it is then 1053ab68143ad0fb784db38a3fd65612632fca90c789Jean Chalard // we want to show suggestions anyway. 10549395014e76877fc9ef060a3fe54a9e06f0036d6dJean Chalard final SettingsValues settingsValues = mSettings.getCurrent(); 1055ab68143ad0fb784db38a3fd65612632fca90c789Jean Chalard if (isInputViewShown() 1056ecea8551c39a497e036be5c010d7ddb6b51a36bcJean Chalard && mInputLogic.onUpdateSelection(oldSelStart, oldSelEnd, newSelStart, newSelEnd, 1057ecea8551c39a497e036be5c010d7ddb6b51a36bcJean Chalard settingsValues)) { 10588ab4ae4377fca97cb9ef05c615c5a59bc4bc3d8cJean Chalard mKeyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(), 10598ab4ae4377fca97cb9ef05c615c5a59bc4bc3d8cJean Chalard getCurrentRecapitalizeState()); 10604733609947c0ec74e460bd714fffca0518ade93aJean Chalard } 10617a8dac55278cedd838be325f56b4c52d973c61f5satok } 10627a8dac55278cedd838be325f56b4c52d973c61f5satok 1063c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani /** 1064c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * This is called when the user has clicked on the extracted text view, 1065c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * when running in fullscreen mode. The default implementation hides 1066913e2aeef26f172d500a4ebfc644b5f47778841aTadashi G. Takaoka * the suggestions view when this happens, but only if the extracted text 1067c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * editor has a vertical scroll bar because its text doesn't fit. 1068c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * Here we override the behavior due to the possibility that a re-correction could 1069913e2aeef26f172d500a4ebfc644b5f47778841aTadashi G. Takaoka * cause the suggestions strip to disappear and re-appear. 1070c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani */ 1071c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani @Override 1072c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani public void onExtractedTextClicked() { 1073ab661e3ef886a36b02fe094864ae4be6a3260f71Tadashi G. Takaoka if (mSettings.getCurrent().needsToLookupSuggestions()) { 1074aa161eb371d8042ef4c1f9207648b3aeacb65e4eJean Chalard return; 1075aa161eb371d8042ef4c1f9207648b3aeacb65e4eJean Chalard } 1076c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 1077c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani super.onExtractedTextClicked(); 1078c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani } 1079c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 1080c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani /** 1081c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * This is called when the user has performed a cursor movement in the 1082c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * extracted text view, when it is running in fullscreen mode. The default 1083913e2aeef26f172d500a4ebfc644b5f47778841aTadashi G. Takaoka * implementation hides the suggestions view when a vertical movement 1084c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * happens, but only if the extracted text editor has a vertical scroll bar 1085c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * because its text doesn't fit. 1086c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani * Here we override the behavior due to the possibility that a re-correction could 1087913e2aeef26f172d500a4ebfc644b5f47778841aTadashi G. Takaoka * cause the suggestions strip to disappear and re-appear. 1088c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani */ 1089c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani @Override 1090f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void onExtractedCursorMovement(final int dx, final int dy) { 1091ab661e3ef886a36b02fe094864ae4be6a3260f71Tadashi G. Takaoka if (mSettings.getCurrent().needsToLookupSuggestions()) { 1092aa161eb371d8042ef4c1f9207648b3aeacb65e4eJean Chalard return; 1093aa161eb371d8042ef4c1f9207648b3aeacb65e4eJean Chalard } 1094c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 1095c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani super.onExtractedCursorMovement(dx, dy); 1096c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani } 1097c1020c3aa65b1eef4c672564750c020d012c4ec2Amith Yamasani 1098923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 1099923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project public void hideWindow() { 1100c3d175c01ff1956ddb1c2d608d69af1793b4ad8aTadashi G. Takaoka mKeyboardSwitcher.onHideWindow(); 1101979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1102923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project if (TRACE) Debug.stopMethodTracing(); 110330d5ed67d6548a4d7efa6354d41ac9719a4e4488Tadashi G. Takaoka if (isShowingOptionDialog()) { 11046e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani mOptionsDialog.dismiss(); 11056e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani mOptionsDialog = null; 11066e3d427c320e89c6155cbcf4045e399b9b55f48fAmith Yamasani } 1107923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.hideWindow(); 1108923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1109923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1110923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 1111f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void onDisplayCompletions(final CompletionInfo[] applicationSpecifiedCompletions) { 1112edaa83bb32e7299b5bba2c42d703701c1e2a3d5bDan Zivkovic if (DebugFlags.DEBUG_ENABLED) { 1113a776b7fc4a0d2c7f05eaed107e9d5db3b575b9d0Ken Wakasa Log.i(TAG, "Received completions:"); 1114bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok if (applicationSpecifiedCompletions != null) { 1115bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok for (int i = 0; i < applicationSpecifiedCompletions.length; i++) { 1116bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok Log.i(TAG, " #" + i + ": " + applicationSpecifiedCompletions[i]); 1117bcfce3b3b9dbd4f5db736948b74bd820fc639a08satok } 1118923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1119923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 11202312c1954f86b5fd3b8e5099da814ad73e5a5e26Ken Wakasa if (!mSettings.getCurrent().isApplicationSpecifiedCompletionsOn()) { 11212312c1954f86b5fd3b8e5099da814ad73e5a5e26Ken Wakasa return; 11222312c1954f86b5fd3b8e5099da814ad73e5a5e26Ken Wakasa } 1123e2744c6384b49b9e90837be92e78613224ea8a33Jean Chalard // If we have an update request in flight, we need to cancel it so it does not override 1124e2744c6384b49b9e90837be92e78613224ea8a33Jean Chalard // these completions. 1125e2744c6384b49b9e90837be92e78613224ea8a33Jean Chalard mHandler.cancelUpdateSuggestionStrip(); 1126dca729fddd69f03d8eaca238c62478a7fd77db96Jean Chalard if (applicationSpecifiedCompletions == null) { 112707eddf3c43859008892c78aa282f203591b4cffcJean Chalard setNeutralSuggestionStrip(); 1128dca729fddd69f03d8eaca238c62478a7fd77db96Jean Chalard return; 1129923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1130dca729fddd69f03d8eaca238c62478a7fd77db96Jean Chalard 1131dca729fddd69f03d8eaca238c62478a7fd77db96Jean Chalard final ArrayList<SuggestedWords.SuggestedWordInfo> applicationSuggestedWords = 1132dca729fddd69f03d8eaca238c62478a7fd77db96Jean Chalard SuggestedWords.getFromApplicationSpecifiedCompletions( 1133dca729fddd69f03d8eaca238c62478a7fd77db96Jean Chalard applicationSpecifiedCompletions); 11342312c1954f86b5fd3b8e5099da814ad73e5a5e26Ken Wakasa final SuggestedWords suggestedWords = new SuggestedWords(applicationSuggestedWords, 113583f9524b8796d94fad56280f6b26c9045fea313fJean Chalard null /* rawSuggestions */, 113683f9524b8796d94fad56280f6b26c9045fea313fJean Chalard null /* typedWord */, 113783f9524b8796d94fad56280f6b26c9045fea313fJean Chalard false /* typedWordValid */, 113883f9524b8796d94fad56280f6b26c9045fea313fJean Chalard false /* willAutoCorrect */, 11398380f921f7edaeea2033a1e967a14941400fe246Jean Chalard false /* isObsoleteSuggestions */, 114083f9524b8796d94fad56280f6b26c9045fea313fJean Chalard SuggestedWords.INPUT_STYLE_APPLICATION_SPECIFIED /* inputStyle */, 114183f9524b8796d94fad56280f6b26c9045fea313fJean Chalard SuggestedWords.NOT_A_SEQUENCE_NUMBER); 11422312c1954f86b5fd3b8e5099da814ad73e5a5e26Ken Wakasa // When in fullscreen mode, show completions generated by the application forcibly 1143987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka setSuggestedWords(suggestedWords); 1144923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1145923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1146543dbdfdbda259aa56be9670480c7d802beba332Ken Wakasa @Override 1147f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void onComputeInsets(final InputMethodService.Insets outInsets) { 1148923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.onComputeInsets(outInsets); 114996d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka // This method may be called before {@link #setInputView(View)}. 115096d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka if (mInputView == null) { 115196d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka return; 115296d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka } 11536bb6d30344259b41387f15f0e05df2388beb1d1cJean Chalard final SettingsValues settingsValues = mSettings.getCurrent(); 115456e1b7e4f112a268371c84606e6f4239aef91333Ken Wakasa final View visibleKeyboardView = mKeyboardSwitcher.getVisibleKeyboardView(); 115512ff7da19df29511e489f426f372300a674f756aKen Wakasa if (visibleKeyboardView == null || !hasSuggestionStripView()) { 115646ca84584810dfe606e709b3fe283cbde8aba5f5Tadashi G. Takaoka return; 115727e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka } 115837beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka final int inputHeight = mInputView.getHeight(); 11591fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic if (isImeSuppressedByHardwareKeyboard() && !visibleKeyboardView.isShown()) { 11608fdff5a11129827e88ce9f5bc462e18f613c19a3Tadashi G. Takaoka // If there is a hardware keyboard and a visible software keyboard view has been hidden, 11618fdff5a11129827e88ce9f5bc462e18f613c19a3Tadashi G. Takaoka // no visual element will be shown on the screen. 116298dfa6e3346b95f3da8869048715e2e18f85d65eTadashi G. Takaoka outInsets.contentTopInsets = inputHeight; 116337beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka outInsets.visibleTopInsets = inputHeight; 116415480481be790c913b0117d0841565efd399cd01Tadashi G. Takaoka mInsetsUpdater.setInsets(outInsets); 11658fdff5a11129827e88ce9f5bc462e18f613c19a3Tadashi G. Takaoka return; 11668fdff5a11129827e88ce9f5bc462e18f613c19a3Tadashi G. Takaoka } 116737beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka final int suggestionsHeight = (!mKeyboardSwitcher.isShowingEmojiPalettes() 116837beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka && mSuggestionStripView.getVisibility() == View.VISIBLE) 116937beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka ? mSuggestionStripView.getHeight() : 0; 1170be819dbe2b7a5c418530a2fa1182766a4d31d6d5Tadashi G. Takaoka final int visibleTopY = inputHeight - visibleKeyboardView.getHeight() - suggestionsHeight; 117137beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka mSuggestionStripView.setMoreSuggestionsHeight(visibleTopY); 117298dfa6e3346b95f3da8869048715e2e18f85d65eTadashi G. Takaoka // Need to set expanded touchable region only if a keyboard view is being shown. 117356e1b7e4f112a268371c84606e6f4239aef91333Ken Wakasa if (visibleKeyboardView.isShown()) { 117437beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka final int touchLeft = 0; 117537beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka final int touchTop = mKeyboardSwitcher.isShowingMoreKeysPanel() ? 0 : visibleTopY; 1176be819dbe2b7a5c418530a2fa1182766a4d31d6d5Tadashi G. Takaoka final int touchRight = visibleKeyboardView.getWidth(); 117737beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka final int touchBottom = inputHeight 11787a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka // Extend touchable region below the keyboard. 11797a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92Tadashi G. Takaoka + EXTENDED_TOUCHABLE_REGION_HEIGHT; 118013d6ecc4c275b9e9c38c7713bb2c69d37f3467f3Tadashi G. Takaoka outInsets.touchableInsets = InputMethodService.Insets.TOUCHABLE_INSETS_REGION; 118137beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka outInsets.touchableRegion.set(touchLeft, touchTop, touchRight, touchBottom); 11829e347d3d448e48229c46aad394ec9bd60cd5807bsatok } 1183c160a3932f74fea72c5347798c001d4ae961864cKen Wakasa outInsets.contentTopInsets = visibleTopY; 1184c160a3932f74fea72c5347798c001d4ae961864cKen Wakasa outInsets.visibleTopInsets = visibleTopY; 118515480481be790c913b0117d0841565efd399cd01Tadashi G. Takaoka mInsetsUpdater.setInsets(outInsets); 1186923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1187a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 118896d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka public void startShowingInputView(final boolean needsToLoadKeyboard) { 118988f282de0dbb92c7d423c30a84395893d6765092Tadashi G. Takaoka mIsExecutingStartShowingInputView = true; 119088f282de0dbb92c7d423c30a84395893d6765092Tadashi G. Takaoka // This {@link #showWindow(boolean)} will eventually call back 119188f282de0dbb92c7d423c30a84395893d6765092Tadashi G. Takaoka // {@link #onEvaluateInputViewShown()}. 119288f282de0dbb92c7d423c30a84395893d6765092Tadashi G. Takaoka showWindow(true /* showInput */); 119388f282de0dbb92c7d423c30a84395893d6765092Tadashi G. Takaoka mIsExecutingStartShowingInputView = false; 119496d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka if (needsToLoadKeyboard) { 119596d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka loadKeyboard(); 119696d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka } 119788f282de0dbb92c7d423c30a84395893d6765092Tadashi G. Takaoka } 119888f282de0dbb92c7d423c30a84395893d6765092Tadashi G. Takaoka 119988f282de0dbb92c7d423c30a84395893d6765092Tadashi G. Takaoka public void stopShowingInputView() { 120088f282de0dbb92c7d423c30a84395893d6765092Tadashi G. Takaoka showWindow(false /* showInput */); 12018fdff5a11129827e88ce9f5bc462e18f613c19a3Tadashi G. Takaoka } 12028fdff5a11129827e88ce9f5bc462e18f613c19a3Tadashi G. Takaoka 12038fdff5a11129827e88ce9f5bc462e18f613c19a3Tadashi G. Takaoka @Override 120496d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka public boolean onShowInputRequested(final int flags, final boolean configChange) { 12051fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic if (isImeSuppressedByHardwareKeyboard()) { 120696d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka return true; 120796d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka } 120896d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka return super.onShowInputRequested(flags, configChange); 120996d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka } 121096d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka 121196d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka @Override 121288f282de0dbb92c7d423c30a84395893d6765092Tadashi G. Takaoka public boolean onEvaluateInputViewShown() { 121388f282de0dbb92c7d423c30a84395893d6765092Tadashi G. Takaoka if (mIsExecutingStartShowingInputView) { 121419dd34a02320b7a368c4ad65398248ceca41b69eTadashi G. Takaoka return true; 121519dd34a02320b7a368c4ad65398248ceca41b69eTadashi G. Takaoka } 121688f282de0dbb92c7d423c30a84395893d6765092Tadashi G. Takaoka return super.onEvaluateInputViewShown(); 121719dd34a02320b7a368c4ad65398248ceca41b69eTadashi G. Takaoka } 121819dd34a02320b7a368c4ad65398248ceca41b69eTadashi G. Takaoka 121919dd34a02320b7a368c4ad65398248ceca41b69eTadashi G. Takaoka @Override 1220979f8690967ff5409fe18f5085858ccdb8e0ccf1satok public boolean onEvaluateFullscreenMode() { 12216bb6d30344259b41387f15f0e05df2388beb1d1cJean Chalard final SettingsValues settingsValues = mSettings.getCurrent(); 12221fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic if (isImeSuppressedByHardwareKeyboard()) { 12238fdff5a11129827e88ce9f5bc462e18f613c19a3Tadashi G. Takaoka // If there is a hardware keyboard, disable full screen mode. 12248fdff5a11129827e88ce9f5bc462e18f613c19a3Tadashi G. Takaoka return false; 12258fdff5a11129827e88ce9f5bc462e18f613c19a3Tadashi G. Takaoka } 122630a72da42c479adb4cedff5d7a40846a3103ac9bJean Chalard // Reread resource value here, because this method is called by the framework as needed. 12272fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final boolean isFullscreenModeAllowed = Settings.readUseFullscreenMode(getResources()); 122860dea36dafc4a567b948b5175bcca776b08fdfadSatoshi Kataoka if (super.onEvaluateFullscreenMode() && isFullscreenModeAllowed) { 122960dea36dafc4a567b948b5175bcca776b08fdfadSatoshi Kataoka // TODO: Remove this hack. Actually we should not really assume NO_EXTRACT_UI 123060dea36dafc4a567b948b5175bcca776b08fdfadSatoshi Kataoka // implies NO_FULLSCREEN. However, the framework mistakenly does. i.e. NO_EXTRACT_UI 123160dea36dafc4a567b948b5175bcca776b08fdfadSatoshi Kataoka // without NO_FULLSCREEN doesn't work as expected. Because of this we need this 123260dea36dafc4a567b948b5175bcca776b08fdfadSatoshi Kataoka // hack for now. Let's get rid of this once the framework gets fixed. 123360dea36dafc4a567b948b5175bcca776b08fdfadSatoshi Kataoka final EditorInfo ei = getCurrentInputEditorInfo(); 123460dea36dafc4a567b948b5175bcca776b08fdfadSatoshi Kataoka return !(ei != null && ((ei.imeOptions & EditorInfo.IME_FLAG_NO_EXTRACT_UI) != 0)); 123560dea36dafc4a567b948b5175bcca776b08fdfadSatoshi Kataoka } 123688f282de0dbb92c7d423c30a84395893d6765092Tadashi G. Takaoka return false; 123759010a89b839ea181dc07588df21f3db29ee8bd1Tadashi G. Takaoka } 123859010a89b839ea181dc07588df21f3db29ee8bd1Tadashi G. Takaoka 123959010a89b839ea181dc07588df21f3db29ee8bd1Tadashi G. Takaoka @Override 124059010a89b839ea181dc07588df21f3db29ee8bd1Tadashi G. Takaoka public void updateFullscreenMode() { 124196d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka super.updateFullscreenMode(); 124296d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka updateSoftInputWindowLayoutParameters(); 124396d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka } 124496d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka 124596d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka private void updateSoftInputWindowLayoutParameters() { 124637beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka // Override layout parameters to expand {@link SoftInputWindow} to the entire screen. 124796d31df8c452a2a6230a5e8c03b0cab1ab13ff80Tadashi G. Takaoka // See {@link InputMethodService#setinputView(View)} and 124837beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka // {@link SoftInputWindow#updateWidthHeight(WindowManager.LayoutParams)}. 124937beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka final Window window = getWindow().getWindow(); 125037beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka ViewLayoutUtils.updateLayoutHeightOf(window, LayoutParams.MATCH_PARENT); 125137beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka // This method may be called before {@link #setInputView(View)}. 125237beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka if (mInputView != null) { 125337beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka // In non-fullscreen mode, {@link InputView} and its parent inputArea should expand to 125437beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka // the entire screen and be placed at the bottom of {@link SoftInputWindow}. 125537beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka // In fullscreen mode, these shouldn't expand to the entire screen and should be 125637beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka // coexistent with {@link #mExtractedArea} above. 125737beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka // See {@link InputMethodService#setInputView(View) and 125837beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka // com.android.internal.R.layout.input_method.xml. 125937beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka final int layoutHeight = isFullscreenMode() 126037beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka ? LayoutParams.WRAP_CONTENT : LayoutParams.MATCH_PARENT; 126137beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka final View inputArea = window.findViewById(android.R.id.inputArea); 126237beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka ViewLayoutUtils.updateLayoutHeightOf(inputArea, layoutHeight); 126337beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka ViewLayoutUtils.updateLayoutGravityOf(inputArea, Gravity.BOTTOM); 126437beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka ViewLayoutUtils.updateLayoutHeightOf(mInputView, layoutHeight); 126537beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka } 1266979f8690967ff5409fe18f5085858ccdb8e0ccf1satok } 1267979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 12685f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka int getCurrentAutoCapsState() { 126910460441db805e78c3384cdba4fe011996221534Jean Chalard return mInputLogic.getCurrentAutoCapsState(mSettings.getCurrent()); 12701c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani } 12711c551251106e506c70fad7ba0cb8b1e2a7dff3a9Amith Yamasani 12725f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka int getCurrentRecapitalizeState() { 127348ba1f25ffb40780fb97093ee9a8ce118a801740Jean Chalard return mInputLogic.getCurrentRecapitalizeState(); 12748094bf45d73a5f7257076afc97d91d6708ee03c4Jean Chalard } 12758094bf45d73a5f7257076afc97d91d6708ee03c4Jean Chalard 1276d1f463eacfaac31a999f7eb1ecaa1668ed3038d4Jean Chalard /** 1277d1f463eacfaac31a999f7eb1ecaa1668ed3038d4Jean Chalard * @param codePoints code points to get coordinates for. 1278d1f463eacfaac31a999f7eb1ecaa1668ed3038d4Jean Chalard * @return x,y coordinates for this keyboard, as a flattened array. 1279d1f463eacfaac31a999f7eb1ecaa1668ed3038d4Jean Chalard */ 1280d1f463eacfaac31a999f7eb1ecaa1668ed3038d4Jean Chalard public int[] getCoordinatesForCurrentKeyboard(final int[] codePoints) { 12811d6e647ac31eab38f30b8ed468551d1e3a07c705Jean Chalard final Keyboard keyboard = mKeyboardSwitcher.getKeyboard(); 12821d6e647ac31eab38f30b8ed468551d1e3a07c705Jean Chalard if (null == keyboard) { 12831d6e647ac31eab38f30b8ed468551d1e3a07c705Jean Chalard return CoordinateUtils.newCoordinateArray(codePoints.length, 12841d6e647ac31eab38f30b8ed468551d1e3a07c705Jean Chalard Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE); 1285d1f463eacfaac31a999f7eb1ecaa1668ed3038d4Jean Chalard } 128688f282de0dbb92c7d423c30a84395893d6765092Tadashi G. Takaoka return keyboard.getCoordinates(codePoints); 1287d1f463eacfaac31a999f7eb1ecaa1668ed3038d4Jean Chalard } 1288d1f463eacfaac31a999f7eb1ecaa1668ed3038d4Jean Chalard 12898a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka // Callback for the {@link SuggestionStripView}, to call when the important notice strip is 12908a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka // pressed. 12918a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka @Override 12928a296e43c903a3377f28943ba4a59082ae7fe60aTadashi G. Takaoka public void showImportantNoticeContents() { 1293604158669b407a40cd0f23538fad4dce5d738f24Mohammadinamul Sheik PermissionsManager.get(this).requestPermissions( 1294604158669b407a40cd0f23538fad4dce5d738f24Mohammadinamul Sheik this /* PermissionsResultCallback */, 1295604158669b407a40cd0f23538fad4dce5d738f24Mohammadinamul Sheik null /* activity */, permission.READ_CONTACTS); 1296d73044a2494873a4abe0d4da208533164314d2f0Tadashi G. Takaoka } 1297d73044a2494873a4abe0d4da208533164314d2f0Tadashi G. Takaoka 1298d73044a2494873a4abe0d4da208533164314d2f0Tadashi G. Takaoka @Override 1299604158669b407a40cd0f23538fad4dce5d738f24Mohammadinamul Sheik public void onRequestPermissionsResult(boolean allGranted) { 1300604158669b407a40cd0f23538fad4dce5d738f24Mohammadinamul Sheik ImportantNoticeUtils.updateContactsNoticeShown(this /* context */); 1301d73044a2494873a4abe0d4da208533164314d2f0Tadashi G. Takaoka setNeutralSuggestionStrip(); 13026abc852255072e9c5741a7d8f264bec99b0ce14eTadashi G. Takaoka } 13036abc852255072e9c5741a7d8f264bec99b0ce14eTadashi G. Takaoka 13045c9e677c2abc6529c19fcc858ef987756d4341efJean Chalard public void displaySettingsDialog() { 130512ff7da19df29511e489f426f372300a674f756aKen Wakasa if (isShowingOptionDialog()) { 130612ff7da19df29511e489f426f372300a674f756aKen Wakasa return; 130712ff7da19df29511e489f426f372300a674f756aKen Wakasa } 1308911b8f9d19c1c4903eeef29b43176cfeaa0e5d0cKen Wakasa showSubtypeSelectorAndSettings(); 13099a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 13109a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok 1311cadb2128f54b49be31bb4dc06374afe81ed028b7Ken Wakasa @Override 1312f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public boolean onCustomRequest(final int requestCode) { 1313cadb2128f54b49be31bb4dc06374afe81ed028b7Ken Wakasa if (isShowingOptionDialog()) return false; 1314cadb2128f54b49be31bb4dc06374afe81ed028b7Ken Wakasa switch (requestCode) { 1315f87e8f7ec1efb93398d909c67468d716b0248fe7Tadashi G. Takaoka case Constants.CUSTOM_CODE_SHOW_INPUT_METHOD_PICKER: 13166fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka if (mRichImm.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) { 13176fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka mRichImm.getInputMethodManager().showInputMethodPicker(); 1318cadb2128f54b49be31bb4dc06374afe81ed028b7Ken Wakasa return true; 13199a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 1320cadb2128f54b49be31bb4dc06374afe81ed028b7Ken Wakasa return false; 13219a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 1322cadb2128f54b49be31bb4dc06374afe81ed028b7Ken Wakasa return false; 13239a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 13249a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok 13259a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok private boolean isShowingOptionDialog() { 13269a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok return mOptionsDialog != null && mOptionsDialog.isShowing(); 13279a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok } 13289a6a4d3d5f1ee52b56d349c002aa61c264d010d3satok 1329809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa public void switchLanguage(final InputMethodSubtype subtype) { 1330809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa final IBinder token = getWindow().getWindow().getAttributes().token; 1331809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa mRichImm.setInputMethodAndSubtype(token, subtype); 1332809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa } 1333809c93214bd85f038c3abb09d8dee60f778b7746Yohei Yukawa 1334aec5cc84760b47661ccc5a0c938368d3798be6b4Tadashi G. Takaoka // TODO: Revise the language switch key behavior to make it much smarter and more reasonable. 133548ba1f25ffb40780fb97093ee9a8ce118a801740Jean Chalard public void switchToNextSubtype() { 133681d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaoka final IBinder token = getWindow().getWindow().getAttributes().token; 13378ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa if (shouldSwitchToOtherInputMethods()) { 13386fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaoka mRichImm.switchToNextInputMethod(token, false /* onlyCurrentIme */); 1339aec5cc84760b47661ccc5a0c938368d3798be6b4Tadashi G. Takaoka return; 1340aec5cc84760b47661ccc5a0c938368d3798be6b4Tadashi G. Takaoka } 13411931c1cab1c2b077030210f2dd7a1839da7211bcTadashi G. Takaoka mSubtypeState.switchSubtype(token, mRichImm); 134281d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaoka } 134381d4e3cd66a9388c47c7dba55240ddf849b31934Tadashi G. Takaoka 1344908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard // TODO: Instead of checking for alphabetic keyboard here, separate keycodes for 1345908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard // alphabetic shift and shift while in symbol layout and get rid of this method. 1346908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard private int getCodePointForKeyboard(final int codePoint) { 1347908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard if (Constants.CODE_SHIFT == codePoint) { 1348908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard final Keyboard currentKeyboard = mKeyboardSwitcher.getKeyboard(); 1349908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard if (null != currentKeyboard && currentKeyboard.mId.isAlphabetKeyboard()) { 1350908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard return codePoint; 1351908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard } 13525f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka return Constants.CODE_SYMBOL_SHIFT; 1353908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard } 13545f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka return codePoint; 1355908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard } 1356908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard 13575f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka // Implementation of {@link KeyboardActionListener}. 13585a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 13592282e8520a2c1984989a14fb09896536f5033b26Jean Chalard public void onCodeInput(final int codePoint, final int x, final int y, 13602282e8520a2c1984989a14fb09896536f5033b26Jean Chalard final boolean isKeyRepeat) { 1361908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard // TODO: this processing does not belong inside LatinIME, the caller should be doing this. 1362352286a43b0f951a5082ca741c2bd7f501f48c81Jean Chalard final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); 1363352286a43b0f951a5082ca741c2bd7f501f48c81Jean Chalard // x and y include some padding, but everything down the line (especially native 1364352286a43b0f951a5082ca741c2bd7f501f48c81Jean Chalard // code) needs the coordinates in the keyboard frame. 1365352286a43b0f951a5082ca741c2bd7f501f48c81Jean Chalard // TODO: We should reconsider which coordinate system should be used to represent 1366352286a43b0f951a5082ca741c2bd7f501f48c81Jean Chalard // keyboard event. Also we should pull this up -- LatinIME has no business doing 1367e38043849e01adfb2f6eb33cf6133c1d39d2466aJean Chalard // this transformation, it should be done already before calling onEvent. 1368a91dfff5e54f68c4003327eeca47286084c35a2fJean Chalard final int keyX = mainKeyboardView.getKeyX(x); 1369a91dfff5e54f68c4003327eeca47286084c35a2fJean Chalard final int keyY = mainKeyboardView.getKeyY(y); 1370908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard final Event event = createSoftwareKeypressEvent(getCodePointForKeyboard(codePoint), 1371908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard keyX, keyY, isKeyRepeat); 1372908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard onEvent(event); 1373908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard } 1374908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard 1375908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard // This method is public for testability of LatinIME, but also in the future it should 1376908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard // completely replace #onCodeInput. 1377d3a4c5132422b189c8dbb94dbbe84a9b9761b0a8Tadashi G. Takaoka public void onEvent(@Nonnull final Event event) { 1378e38043849e01adfb2f6eb33cf6133c1d39d2466aJean Chalard if (Constants.CODE_SHORTCUT == event.mKeyCode) { 13794486314225c4bbb97f35cdbdbb2da1de4fc28be2Tadashi G. Takaoka mRichImm.switchToShortcutIme(this); 1380969c06072db7f530806a4d0581ce588f01d09dc2Jean Chalard } 1381a1bf550294dfb5e6e7e5eba78a8db491c5bab2d4Jean Chalard final InputTransaction completeInputTransaction = 1382a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalard mInputLogic.onCodeInput(mSettings.getCurrent(), event, 138335c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard mKeyboardSwitcher.getKeyboardShiftMode(), 138435c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard mKeyboardSwitcher.getCurrentKeyboardScriptId(), mHandler); 13856bd3723e733308a8b6d88830335bb5f786235369Jean Chalard updateStateAfterInputTransaction(completeInputTransaction); 1386e38043849e01adfb2f6eb33cf6133c1d39d2466aJean Chalard mKeyboardSwitcher.onEvent(event, getCurrentAutoCapsState(), getCurrentRecapitalizeState()); 1387923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1388a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1389a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalard // A helper method to split the code point and the key code. Ultimately, they should not be 1390a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalard // squashed into the same variable, and this method should be removed. 1391908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard // public for testing, as we don't want to copy the same logic into test code 1392d3a4c5132422b189c8dbb94dbbe84a9b9761b0a8Tadashi G. Takaoka @Nonnull 1393908f0ed1541d1f5a9cb6d89d06ec39c219d079bdJean Chalard public static Event createSoftwareKeypressEvent(final int keyCodeOrCodePoint, final int keyX, 13942282e8520a2c1984989a14fb09896536f5033b26Jean Chalard final int keyY, final boolean isKeyRepeat) { 1395a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalard final int keyCode; 1396a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalard final int codePoint; 1397a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalard if (keyCodeOrCodePoint <= 0) { 1398a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalard keyCode = keyCodeOrCodePoint; 1399a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalard codePoint = Event.NOT_A_CODE_POINT; 1400a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalard } else { 1401a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalard keyCode = Event.NOT_A_KEY_CODE; 1402a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalard codePoint = keyCodeOrCodePoint; 1403a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalard } 14042282e8520a2c1984989a14fb09896536f5033b26Jean Chalard return Event.createSoftwareKeypressEvent(codePoint, keyCode, keyX, keyY, isKeyRepeat); 1405a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalard } 1406a79a3265db6482a0bcaf0dfa87036a9243af281dJean Chalard 1407e193c5255d96d3971ee207b459a8a1e91c0d176cYuichiro Hanada // Called from PointerTracker through the KeyboardActionListener interface 1408e193c5255d96d3971ee207b459a8a1e91c0d176cYuichiro Hanada @Override 1409e193c5255d96d3971ee207b459a8a1e91c0d176cYuichiro Hanada public void onTextInput(final String rawText) { 1410058a38988b607e1364e6491b97960d2044ad5068Jean Chalard // TODO: have the keyboard pass the correct key code when we need it. 1411e38043849e01adfb2f6eb33cf6133c1d39d2466aJean Chalard final Event event = Event.createSoftwareTextEvent(rawText, Constants.CODE_OUTPUT_TEXT); 14126345562e2b351221a9bc0341f7dbd26095290b64Jean Chalard final InputTransaction completeInputTransaction = 14136345562e2b351221a9bc0341f7dbd26095290b64Jean Chalard mInputLogic.onTextInput(mSettings.getCurrent(), event, 14146345562e2b351221a9bc0341f7dbd26095290b64Jean Chalard mKeyboardSwitcher.getKeyboardShiftMode(), mHandler); 14156345562e2b351221a9bc0341f7dbd26095290b64Jean Chalard updateStateAfterInputTransaction(completeInputTransaction); 1416e38043849e01adfb2f6eb33cf6133c1d39d2466aJean Chalard mKeyboardSwitcher.onEvent(event, getCurrentAutoCapsState(), getCurrentRecapitalizeState()); 1417923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1418923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 14194be03befe3cf771a33448367f50c517dc01ced21Tadashi G. Takaoka @Override 14204be03befe3cf771a33448367f50c517dc01ced21Tadashi G. Takaoka public void onStartBatchInput() { 14212ca916c215e46d192391e2963037072bafff8ce3Jean Chalard mInputLogic.onStartBatchInput(mSettings.getCurrent(), mKeyboardSwitcher, mHandler); 1422c92c883fdf2287b49392692fa2e8d109dc26f785David Faden mGestureConsumer.onGestureStarted( 1423107fb4c476779df16be23e245547253978c197acDan Zivkovic mRichImm.getCurrentSubtypeLocale(), 1424c92c883fdf2287b49392692fa2e8d109dc26f785David Faden mKeyboardSwitcher.getKeyboard()); 14251587be697752b12e18d5cadb90e56883cb93c242Jean Chalard } 14261587be697752b12e18d5cadb90e56883cb93c242Jean Chalard 14271587be697752b12e18d5cadb90e56883cb93c242Jean Chalard @Override 14281587be697752b12e18d5cadb90e56883cb93c242Jean Chalard public void onUpdateBatchInput(final InputPointers batchPointers) { 1429fe716f0f73ee551ce42b523983f92efccce79dc8Dan Zivkovic mInputLogic.onUpdateBatchInput(batchPointers); 14301587be697752b12e18d5cadb90e56883cb93c242Jean Chalard } 14311587be697752b12e18d5cadb90e56883cb93c242Jean Chalard 14321587be697752b12e18d5cadb90e56883cb93c242Jean Chalard @Override 14331587be697752b12e18d5cadb90e56883cb93c242Jean Chalard public void onEndBatchInput(final InputPointers batchPointers) { 1434151761a2764c09c0e5bc48c68e0c804aeaf22d11Jean Chalard mInputLogic.onEndBatchInput(batchPointers); 1435c92c883fdf2287b49392692fa2e8d109dc26f785David Faden mGestureConsumer.onGestureCompleted(batchPointers); 14361587be697752b12e18d5cadb90e56883cb93c242Jean Chalard } 14371587be697752b12e18d5cadb90e56883cb93c242Jean Chalard 14381587be697752b12e18d5cadb90e56883cb93c242Jean Chalard @Override 14391587be697752b12e18d5cadb90e56883cb93c242Jean Chalard public void onCancelBatchInput() { 144053c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard mInputLogic.onCancelBatchInput(mHandler); 1441c92c883fdf2287b49392692fa2e8d109dc26f785David Faden mGestureConsumer.onGestureCanceled(); 1442c92c883fdf2287b49392692fa2e8d109dc26f785David Faden } 1443c92c883fdf2287b49392692fa2e8d109dc26f785David Faden 1444c92c883fdf2287b49392692fa2e8d109dc26f785David Faden /** 1445f296e7cdfa3af2f666c182f04ea5c3f10945de40Ken Wakasa * To be called after the InputLogic has gotten a chance to act on the suggested words by the 1446f296e7cdfa3af2f666c182f04ea5c3f10945de40Ken Wakasa * IME for the full gesture, possibly updating the TextView to reflect the first suggestion. 1447c92c883fdf2287b49392692fa2e8d109dc26f785David Faden * <p> 1448c92c883fdf2287b49392692fa2e8d109dc26f785David Faden * This method must be run on the UI Thread. 1449f296e7cdfa3af2f666c182f04ea5c3f10945de40Ken Wakasa * @param suggestedWords suggested words by the IME for the full gesture. 1450c92c883fdf2287b49392692fa2e8d109dc26f785David Faden */ 1451c92c883fdf2287b49392692fa2e8d109dc26f785David Faden public void onTailBatchInputResultShown(final SuggestedWords suggestedWords) { 1452c92c883fdf2287b49392692fa2e8d109dc26f785David Faden mGestureConsumer.onImeSuggestionsProcessed(suggestedWords, 14536e86632311a24af90ad35c98224ae25f226c1954David Faden mInputLogic.getComposingStart(), mInputLogic.getComposingLength(), 14546e86632311a24af90ad35c98224ae25f226c1954David Faden mDictionaryFacilitator); 1455f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka } 1456f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka 145752a2682b99fc57dea974b21f3d606ed53a802e60Jean Chalard // This method must run on the UI Thread. 14582ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka void showGesturePreviewAndSuggestionStrip(@Nonnull final SuggestedWords suggestedWords, 1459f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka final boolean dismissGestureFloatingPreviewText) { 1460fa7075768da25341bf84e9f87bba09356961e2e8Jean Chalard showSuggestionStrip(suggestedWords); 1461375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); 14622ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka mainKeyboardView.showGestureFloatingPreviewText(suggestedWords, 14632ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka dismissGestureFloatingPreviewText /* dismissDelayed */); 14644be03befe3cf771a33448367f50c517dc01ced21Tadashi G. Takaoka } 14654be03befe3cf771a33448367f50c517dc01ced21Tadashi G. Takaoka 1466a5bb353de92a6a6d010ba1695b9dd22b3a617b77Jean Chalard // Called from PointerTracker through the KeyboardActionListener interface 14675a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 146841016acacfa21354f59ed51db1f85ea3d99bf6a4Tadashi G. Takaoka public void onFinishSlidingInput() { 146941016acacfa21354f59ed51db1f85ea3d99bf6a4Tadashi G. Takaoka // User finished sliding input. 1470f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard mKeyboardSwitcher.onFinishSlidingInput(getCurrentAutoCapsState(), 1471f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard getCurrentRecapitalizeState()); 147241016acacfa21354f59ed51db1f85ea3d99bf6a4Tadashi G. Takaoka } 147341016acacfa21354f59ed51db1f85ea3d99bf6a4Tadashi G. Takaoka 147441016acacfa21354f59ed51db1f85ea3d99bf6a4Tadashi G. Takaoka // Called from PointerTracker through the KeyboardActionListener interface 147541016acacfa21354f59ed51db1f85ea3d99bf6a4Tadashi G. Takaoka @Override 14768aa3f5a3ad6095a3355841ce30bce4877319d0a0Tadashi G. Takaoka public void onCancelInput() { 147783e63ace2a1bd5b3c27d26d914456c2b0def17c5Tadashi G. Takaoka // User released a finger outside any key 147841016acacfa21354f59ed51db1f85ea3d99bf6a4Tadashi G. Takaoka // Nothing to do so far. 147983e63ace2a1bd5b3c27d26d914456c2b0def17c5Tadashi G. Takaoka } 148083e63ace2a1bd5b3c27d26d914456c2b0def17c5Tadashi G. Takaoka 1481ade1aa55b6be938a44b92f7ca6829c53c6258664Jean Chalard public boolean hasSuggestionStripView() { 1482ade1aa55b6be938a44b92f7ca6829c53c6258664Jean Chalard return null != mSuggestionStripView; 1483ade1aa55b6be938a44b92f7ca6829c53c6258664Jean Chalard } 1484ade1aa55b6be938a44b92f7ca6829c53c6258664Jean Chalard 1485987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka private void setSuggestedWords(final SuggestedWords suggestedWords) { 1486bea17c49ec23bf0f646cb548445c7756aa50d233Yohei Yukawa final SettingsValues currentSettingsValues = mSettings.getCurrent(); 1487176ad53c6fee47df7595e7501e7e2829d990364dJean Chalard mInputLogic.setSuggestedWords(suggestedWords); 1488129ca9e7ebc9316a43ae716cc6ec44e1e17a35faJean Chalard // TODO: Modify this when we support suggestions with hard keyboard 148912ff7da19df29511e489f426f372300a674f756aKen Wakasa if (!hasSuggestionStripView()) { 1490affdd364232549d2062fc180f924f5b6496c26fdTadashi G. Takaoka return; 1491675f1dbaf0c9a2e01fe04c07ceb23f6b79721fd0Jean Chalard } 1492129ca9e7ebc9316a43ae716cc6ec44e1e17a35faJean Chalard if (!onEvaluateInputViewShown()) { 1493129ca9e7ebc9316a43ae716cc6ec44e1e17a35faJean Chalard return; 1494129ca9e7ebc9316a43ae716cc6ec44e1e17a35faJean Chalard } 1495aa4b2c71270576f25e7c80a4b63a1956cec5f4e2Tadashi G. Takaoka 1496987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka final boolean shouldShowImportantNotice = 14978ec36026c93d13c1118eda936ac12325e0085561Chieu Nguyen ImportantNoticeUtils.shouldShowImportantNotice(this, currentSettingsValues); 14986a96c508fddde10827b8f0822a7096bf4b708cf0Tadashi G. Takaoka final boolean shouldShowSuggestionCandidates = 14996a96c508fddde10827b8f0822a7096bf4b708cf0Tadashi G. Takaoka currentSettingsValues.mInputAttributes.mShouldShowSuggestions 1500ab661e3ef886a36b02fe094864ae4be6a3260f71Tadashi G. Takaoka && currentSettingsValues.isSuggestionsEnabledPerUserSettings(); 1501987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka final boolean shouldShowSuggestionsStripUnlessPassword = shouldShowImportantNotice 1502987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka || currentSettingsValues.mShowsVoiceInputKey 15036a96c508fddde10827b8f0822a7096bf4b708cf0Tadashi G. Takaoka || shouldShowSuggestionCandidates 1504987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka || currentSettingsValues.isApplicationSpecifiedCompletionsOn(); 1505987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka final boolean shouldShowSuggestionsStrip = shouldShowSuggestionsStripUnlessPassword 1506987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka && !currentSettingsValues.mInputAttributes.mIsPasswordField; 1507987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka mSuggestionStripView.updateVisibility(shouldShowSuggestionsStrip, isFullscreenMode()); 1508987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka if (!shouldShowSuggestionsStrip) { 1509129ca9e7ebc9316a43ae716cc6ec44e1e17a35faJean Chalard return; 1510129ca9e7ebc9316a43ae716cc6ec44e1e17a35faJean Chalard } 1511129ca9e7ebc9316a43ae716cc6ec44e1e17a35faJean Chalard 1512987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka final boolean isEmptyApplicationSpecifiedCompletions = 1513987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka currentSettingsValues.isApplicationSpecifiedCompletionsOn() 1514987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka && suggestedWords.isEmpty(); 151530f4a2a4d750dc8c3132d706d9148daf71fbd168Adrian Velicu final boolean noSuggestionsFromDictionaries = suggestedWords.isEmpty() 15169df51d10fa6b5b21de564cd93926a88690a98600Tadashi G. Takaoka || suggestedWords.isPunctuationSuggestions() 1517987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka || isEmptyApplicationSpecifiedCompletions; 1518f4c7eb478f67874e81cce786bf91ab112da316e1Tadashi G. Takaoka final boolean isBeginningOfSentencePrediction = (suggestedWords.mInputStyle 1519f4c7eb478f67874e81cce786bf91ab112da316e1Tadashi G. Takaoka == SuggestedWords.INPUT_STYLE_BEGINNING_OF_SENTENCE_PREDICTION); 1520f4c7eb478f67874e81cce786bf91ab112da316e1Tadashi G. Takaoka final boolean noSuggestionsToOverrideImportantNotice = noSuggestionsFromDictionaries 1521f4c7eb478f67874e81cce786bf91ab112da316e1Tadashi G. Takaoka || isBeginningOfSentencePrediction; 1522f4c7eb478f67874e81cce786bf91ab112da316e1Tadashi G. Takaoka if (shouldShowImportantNotice && noSuggestionsToOverrideImportantNotice) { 15236a96c508fddde10827b8f0822a7096bf4b708cf0Tadashi G. Takaoka if (mSuggestionStripView.maybeShowImportantNoticeTitle()) { 15246a96c508fddde10827b8f0822a7096bf4b708cf0Tadashi G. Takaoka return; 15256a96c508fddde10827b8f0822a7096bf4b708cf0Tadashi G. Takaoka } 1526affdd364232549d2062fc180f924f5b6496c26fdTadashi G. Takaoka } 1527987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka 1528ab661e3ef886a36b02fe094864ae4be6a3260f71Tadashi G. Takaoka if (currentSettingsValues.isSuggestionsEnabledPerUserSettings() 1529f4c7eb478f67874e81cce786bf91ab112da316e1Tadashi G. Takaoka || currentSettingsValues.isApplicationSpecifiedCompletionsOn() 1530f4c7eb478f67874e81cce786bf91ab112da316e1Tadashi G. Takaoka // We should clear the contextual strip if there is no suggestion from dictionaries. 1531f4c7eb478f67874e81cce786bf91ab112da316e1Tadashi G. Takaoka || noSuggestionsFromDictionaries) { 1532affdd364232549d2062fc180f924f5b6496c26fdTadashi G. Takaoka mSuggestionStripView.setSuggestions(suggestedWords, 15337fb0ed58edd4cc2514f0b5dd5bd2083889ff325cTadashi G. Takaoka mRichImm.getCurrentSubtype().isRtlSubtype()); 1534affdd364232549d2062fc180f924f5b6496c26fdTadashi G. Takaoka } 1535466741d8a78965b8509bf527344f289e50873092Mike LeBeau } 1536466741d8a78965b8509bf527344f289e50873092Mike LeBeau 153753c320e2757ec37e40dc1dc54a2b04a05a995003Jean Chalard // TODO[IL]: Move this out of LatinIME. 1538b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard public void getSuggestedWords(final int inputStyle, final int sequenceNumber, 15399666a228153bb2269da8983762bdd47e448f2cecYuichiro Hanada final OnGetSuggestedWordsCallback callback) { 1540d445b56ce14152b30143302899790af255691148Tadashi G. Takaoka final Keyboard keyboard = mKeyboardSwitcher.getKeyboard(); 1541adfb262797023c4ca57bb470e547f90c88f638caKeisuke Kuroyanagi if (keyboard == null) { 154230f4a2a4d750dc8c3132d706d9148daf71fbd168Adrian Velicu callback.onGetSuggestedWords(SuggestedWords.getEmptyInstance()); 15439666a228153bb2269da8983762bdd47e448f2cecYuichiro Hanada return; 1544d445b56ce14152b30143302899790af255691148Tadashi G. Takaoka } 1545487e038ff329b6099ff5343fb2d7bdc60a6fd699Mario Tanev mInputLogic.getSuggestedWords(mSettings.getCurrent(), keyboard, 1546487e038ff329b6099ff5343fb2d7bdc60a6fd699Mario Tanev mKeyboardSwitcher.getKeyboardShiftMode(), inputStyle, sequenceNumber, callback); 1547ae7d1530b48e31266dbe8c6c5f33481853092170Jean Chalard } 1548ae7d1530b48e31266dbe8c6c5f33481853092170Jean Chalard 1549ade1aa55b6be938a44b92f7ca6829c53c6258664Jean Chalard @Override 155030f4a2a4d750dc8c3132d706d9148daf71fbd168Adrian Velicu public void showSuggestionStrip(final SuggestedWords suggestedWords) { 155130f4a2a4d750dc8c3132d706d9148daf71fbd168Adrian Velicu if (suggestedWords.isEmpty()) { 15522cbf152986a67ddffa909111718bb8d2dc80e5d7Jean Chalard setNeutralSuggestionStrip(); 15532cbf152986a67ddffa909111718bb8d2dc80e5d7Jean Chalard } else { 1554987bff9136ec101d06db7903ebb3f505e4ea78d6Tadashi G. Takaoka setSuggestedWords(suggestedWords); 1555c6367ee64d9e301d8c2e920ada57a5550aafa596Jean Chalard } 1556c6367ee64d9e301d8c2e920ada57a5550aafa596Jean Chalard // Cache the auto-correction in accessibility code so we can speak it if the user 1557c6367ee64d9e301d8c2e920ada57a5550aafa596Jean Chalard // touches a key that will insert it. 1558a94733cbca5bc3544fa73fa1649bbb1dadf31356Jean Chalard AccessibilityUtils.getInstance().setAutoCorrection(suggestedWords); 1559a469743e331e57e3a03354f95268e4addf93b0e8Yuichiro Hanada } 1560a469743e331e57e3a03354f95268e4addf93b0e8Yuichiro Hanada 15614702671ea4feb0c79a879e2e3013afdd6ed800b1Tadashi G. Takaoka // Called from {@link SuggestionStripView} through the {@link SuggestionStripView#Listener} 15624702671ea4feb0c79a879e2e3013afdd6ed800b1Tadashi G. Takaoka // interface 1563c97810693dfe83bf37c09f73c8d4b40f2ba8dddbTadashi G. Takaoka @Override 156435c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard public void pickSuggestionManually(final SuggestedWordInfo suggestionInfo) { 156546e17983c69650415c6469a80c46154cb4299f9dJean Chalard final InputTransaction completeInputTransaction = mInputLogic.onPickSuggestionManually( 156635c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard mSettings.getCurrent(), suggestionInfo, 156735c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard mKeyboardSwitcher.getKeyboardShiftMode(), 156835c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard mKeyboardSwitcher.getCurrentKeyboardScriptId(), 156935c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard mHandler); 15706bd3723e733308a8b6d88830335bb5f786235369Jean Chalard updateStateAfterInputTransaction(completeInputTransaction); 15712bb1c6add961e09c21af92c631f3922f1ab36a91Jean Chalard } 1572979f8690967ff5409fe18f5085858ccdb8e0ccf1satok 1573b2c0388a6961b7df96864ba693a2dd84c1f8a1b0Jean Chalard // This will show either an empty suggestion strip (if prediction is enabled) or 1574b2c0388a6961b7df96864ba693a2dd84c1f8a1b0Jean Chalard // punctuation suggestions (if it's disabled). 1575ade1aa55b6be938a44b92f7ca6829c53c6258664Jean Chalard @Override 1576b2c0388a6961b7df96864ba693a2dd84c1f8a1b0Jean Chalard public void setNeutralSuggestionStrip() { 15775455179b54eb8230577f518db082796a3055685aDan Zivkovic final SettingsValues currentSettings = mSettings.getCurrent(); 15785455179b54eb8230577f518db082796a3055685aDan Zivkovic final SuggestedWords neutralSuggestions = currentSettings.mBigramPredictionEnabled 15795455179b54eb8230577f518db082796a3055685aDan Zivkovic ? SuggestedWords.getEmptyInstance() 15805455179b54eb8230577f518db082796a3055685aDan Zivkovic : currentSettings.mSpacingAndPunctuations.mSuggestPuncList; 15815455179b54eb8230577f518db082796a3055685aDan Zivkovic setSuggestedWords(neutralSuggestions); 15826a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani } 15836a6075caba3865383eeeb52cccc63a28e4ae5900Amith Yamasani 15849fc6af325ec91a1a22c0679d374c0c3d6d03d9acTadashi G. Takaoka // Outside LatinIME, only used by the {@link InputTestsBase} test suite. 158515f6d4ae34664ea3d92827a2c3003198c0bac70bTadashi G. Takaoka @UsedForTesting 15869fc6af325ec91a1a22c0679d374c0c3d6d03d9acTadashi G. Takaoka void loadKeyboard() { 1587673c727b7a42e2cee2df4415111bfa94a0a2df3bJean Chalard // Since we are switching languages, the most urgent thing is to let the keyboard graphics 1588673c727b7a42e2cee2df4415111bfa94a0a2df3bJean Chalard // update. LoadKeyboard does that, but we need to wait for buffer flip for it to be on 1589673c727b7a42e2cee2df4415111bfa94a0a2df3bJean Chalard // the screen. Anything we do right now will delay this, so wait until the next frame 1590673c727b7a42e2cee2df4415111bfa94a0a2df3bJean Chalard // before we do the rest, like reopening dictionaries and updating suggestions. So we 1591673c727b7a42e2cee2df4415111bfa94a0a2df3bJean Chalard // post a message. 1592673c727b7a42e2cee2df4415111bfa94a0a2df3bJean Chalard mHandler.postReopenDictionaries(); 15930657b9698a110f8e895448d829478982ce37b6d1Tadashi G. Takaoka loadSettings(); 159427e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka if (mKeyboardSwitcher.getMainKeyboardView() != null) { 15951e39565bb48d23221145c494d4bf5665b514699dTadashi G. Takaoka // Reload keyboard because the current language has been changed. 1596f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard mKeyboardSwitcher.loadKeyboard(getCurrentInputEditorInfo(), mSettings.getCurrent(), 1597f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard getCurrentAutoCapsState(), getCurrentRecapitalizeState()); 15981e39565bb48d23221145c494d4bf5665b514699dTadashi G. Takaoka } 159936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani } 160036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani 16016bd3723e733308a8b6d88830335bb5f786235369Jean Chalard /** 16026bd3723e733308a8b6d88830335bb5f786235369Jean Chalard * After an input transaction has been executed, some state must be updated. This includes 16036bd3723e733308a8b6d88830335bb5f786235369Jean Chalard * the shift state of the keyboard and suggestions. This method looks at the finished 16046bd3723e733308a8b6d88830335bb5f786235369Jean Chalard * inputTransaction to find out what is necessary and updates the state accordingly. 16056bd3723e733308a8b6d88830335bb5f786235369Jean Chalard * @param inputTransaction The transaction that has been executed. 16066bd3723e733308a8b6d88830335bb5f786235369Jean Chalard */ 16076bd3723e733308a8b6d88830335bb5f786235369Jean Chalard private void updateStateAfterInputTransaction(final InputTransaction inputTransaction) { 16086bd3723e733308a8b6d88830335bb5f786235369Jean Chalard switch (inputTransaction.getRequiredShiftUpdate()) { 160946e17983c69650415c6469a80c46154cb4299f9dJean Chalard case InputTransaction.SHIFT_UPDATE_LATER: 161046e17983c69650415c6469a80c46154cb4299f9dJean Chalard mHandler.postUpdateShiftState(); 161146e17983c69650415c6469a80c46154cb4299f9dJean Chalard break; 161246e17983c69650415c6469a80c46154cb4299f9dJean Chalard case InputTransaction.SHIFT_UPDATE_NOW: 16138ab4ae4377fca97cb9ef05c615c5a59bc4bc3d8cJean Chalard mKeyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(), 16148ab4ae4377fca97cb9ef05c615c5a59bc4bc3d8cJean Chalard getCurrentRecapitalizeState()); 161546e17983c69650415c6469a80c46154cb4299f9dJean Chalard break; 161646e17983c69650415c6469a80c46154cb4299f9dJean Chalard default: // SHIFT_NO_UPDATE 161746e17983c69650415c6469a80c46154cb4299f9dJean Chalard } 16186bd3723e733308a8b6d88830335bb5f786235369Jean Chalard if (inputTransaction.requiresUpdateSuggestions()) { 1619b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard final int inputStyle; 1620b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard if (inputTransaction.mEvent.isSuggestionStripPress()) { 1621b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard // Suggestion strip press: no input. 1622b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard inputStyle = SuggestedWords.INPUT_STYLE_NONE; 1623b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard } else if (inputTransaction.mEvent.isGesture()) { 1624b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard inputStyle = SuggestedWords.INPUT_STYLE_TAIL_BATCH; 1625b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard } else { 1626b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard inputStyle = SuggestedWords.INPUT_STYLE_TYPING; 1627b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard } 1628b8d764772b174cbd37354ffd0009bda56f223dc4Jean Chalard mHandler.postUpdateSuggestionStrip(inputStyle); 16296bd3723e733308a8b6d88830335bb5f786235369Jean Chalard } 16306345562e2b351221a9bc0341f7dbd26095290b64Jean Chalard if (inputTransaction.didAffectContents()) { 16316345562e2b351221a9bc0341f7dbd26095290b64Jean Chalard mSubtypeState.setCurrentSubtypeHasBeenUsed(); 16326345562e2b351221a9bc0341f7dbd26095290b64Jean Chalard } 163346e17983c69650415c6469a80c46154cb4299f9dJean Chalard } 163446e17983c69650415c6469a80c46154cb4299f9dJean Chalard 1635ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka private void hapticAndAudioFeedback(final int code, final int repeatCount) { 16366455172a707a1137eb15db8073774982db9dd1faTadashi G. Takaoka final MainKeyboardView keyboardView = mKeyboardSwitcher.getMainKeyboardView(); 16372fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (keyboardView != null && keyboardView.isInDraggingFinger()) { 16382fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // No need to feedback while finger is dragging. 16396455172a707a1137eb15db8073774982db9dd1faTadashi G. Takaoka return; 16406455172a707a1137eb15db8073774982db9dd1faTadashi G. Takaoka } 1641ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka if (repeatCount > 0) { 16427bd2a75ca180cb5da8ba75500163aa06f332caacJean Chalard if (code == Constants.CODE_DELETE && !mInputLogic.mConnection.canDeleteCharacters()) { 1643ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka // No need to feedback when repeat delete key will have no effect. 1644ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka return; 1645ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka } 1646ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka // TODO: Use event time that the last feedback has been generated instead of relying on 1647ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka // a repeat count to thin out feedback. 1648ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka if (repeatCount % PERIOD_FOR_AUDIO_AND_HAPTIC_FEEDBACK_IN_KEY_REPEAT == 0) { 1649ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka return; 1650ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka } 1651ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka } 1652ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka final AudioAndHapticFeedbackManager feedbackManager = 1653ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka AudioAndHapticFeedbackManager.getInstance(); 1654ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka if (repeatCount == 0) { 1655ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka // TODO: Reconsider how to perform haptic feedback when repeating key. 1656ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka feedbackManager.performHapticFeedback(keyboardView); 16576455172a707a1137eb15db8073774982db9dd1faTadashi G. Takaoka } 1658ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka feedbackManager.performAudioFeedback(code); 16596455172a707a1137eb15db8073774982db9dd1faTadashi G. Takaoka } 16606455172a707a1137eb15db8073774982db9dd1faTadashi G. Takaoka 1661f87e8f7ec1efb93398d909c67468d716b0248fe7Tadashi G. Takaoka // Callback of the {@link KeyboardActionListener}. This is called when a key is depressed; 1662f87e8f7ec1efb93398d909c67468d716b0248fe7Tadashi G. Takaoka // release matching call is {@link #onReleaseKey(int,boolean)} below. 16635a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 1664ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka public void onPressKey(final int primaryCode, final int repeatCount, 16656455172a707a1137eb15db8073774982db9dd1faTadashi G. Takaoka final boolean isSinglePointer) { 1666f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard mKeyboardSwitcher.onPressKey(primaryCode, isSinglePointer, getCurrentAutoCapsState(), 1667f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard getCurrentRecapitalizeState()); 1668ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka hapticAndAudioFeedback(primaryCode, repeatCount); 1669923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1670923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1671f87e8f7ec1efb93398d909c67468d716b0248fe7Tadashi G. Takaoka // Callback of the {@link KeyboardActionListener}. This is called when a key is released; 1672ab16237e69061bb0aa7f882e48e5d93459c22ef3Tadashi G. Takaoka // press matching call is {@link #onPressKey(int,int,boolean)} above. 16735a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka @Override 1674f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void onReleaseKey(final int primaryCode, final boolean withSliding) { 1675ddc163988a7e2e910ff3cac26ed580bac123fda0Jean Chalard mKeyboardSwitcher.onReleaseKey(primaryCode, withSliding, getCurrentAutoCapsState(), 1676ddc163988a7e2e910ff3cac26ed580bac123fda0Jean Chalard getCurrentRecapitalizeState()); 1677923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1678a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 16795eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard private HardwareEventDecoder getHardwareKeyEventDecoder(final int deviceId) { 16805eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard final HardwareEventDecoder decoder = mHardwareEventDecoders.get(deviceId); 16815eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard if (null != decoder) return decoder; 16825eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard // TODO: create the decoder according to the specification 16835eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard final HardwareEventDecoder newDecoder = new HardwareKeyboardEventDecoder(deviceId); 16845eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard mHardwareEventDecoders.put(deviceId, newDecoder); 16855eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard return newDecoder; 16865eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard } 16875eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard 1688cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard // Hooks for hardware keyboard 1689cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard @Override 16905eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) { 16919a438a325b28c8f8884737683237f829c7cb5a15Dmitry Torokhov if (mEmojiAltPhysicalKeyDetector == null) { 16929a438a325b28c8f8884737683237f829c7cb5a15Dmitry Torokhov mEmojiAltPhysicalKeyDetector = new EmojiAltPhysicalKeyDetector( 16939a438a325b28c8f8884737683237f829c7cb5a15Dmitry Torokhov getApplicationContext().getResources()); 16949a438a325b28c8f8884737683237f829c7cb5a15Dmitry Torokhov } 16959a438a325b28c8f8884737683237f829c7cb5a15Dmitry Torokhov mEmojiAltPhysicalKeyDetector.onKeyDown(keyEvent); 16965a5ee95faead8a2ae749067716481e86faf5f113Tadashi G. Takaoka if (!ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED) { 16975eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard return super.onKeyDown(keyCode, keyEvent); 16985eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard } 16995eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard final Event event = getHardwareKeyEventDecoder( 17005eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard keyEvent.getDeviceId()).decodeHardwareKey(keyEvent); 17015eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard // If the event is not handled by LatinIME, we just pass it to the parent implementation. 17025eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard // If it's handled, we return true because we did handle it. 17035eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard if (event.isHandled()) { 17045eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard mInputLogic.onCodeInput(mSettings.getCurrent(), event, 170535c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard mKeyboardSwitcher.getKeyboardShiftMode(), 170635c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard // TODO: this is not necessarily correct for a hardware keyboard right now 170735c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard mKeyboardSwitcher.getCurrentKeyboardScriptId(), 170835c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard mHandler); 1709976a42b873215a669fe22709960aa1259292d75cJean Chalard return true; 1710976a42b873215a669fe22709960aa1259292d75cJean Chalard } 17115eac728b4aba43b8f4dabbb0dbc50acdbaaa5f22Jean Chalard return super.onKeyDown(keyCode, keyEvent); 1712cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard } 1713cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard 1714cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard @Override 1715499153734e6dcd01ae9630bf423fadd25628339cTadashi G. Takaoka public boolean onKeyUp(final int keyCode, final KeyEvent keyEvent) { 17161fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic if (mEmojiAltPhysicalKeyDetector == null) { 17171fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic mEmojiAltPhysicalKeyDetector = new EmojiAltPhysicalKeyDetector( 17181fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic getApplicationContext().getResources()); 17191fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic } 1720f7e01e866ffa89b4dd7e66c471ed9fc275a637a2Tadashi G. Takaoka mEmojiAltPhysicalKeyDetector.onKeyUp(keyEvent); 1721499153734e6dcd01ae9630bf423fadd25628339cTadashi G. Takaoka if (!ProductionFlags.IS_HARDWARE_KEYBOARD_SUPPORTED) { 1722499153734e6dcd01ae9630bf423fadd25628339cTadashi G. Takaoka return super.onKeyUp(keyCode, keyEvent); 1723499153734e6dcd01ae9630bf423fadd25628339cTadashi G. Takaoka } 1724499153734e6dcd01ae9630bf423fadd25628339cTadashi G. Takaoka final long keyIdentifier = keyEvent.getDeviceId() << 32 + keyEvent.getKeyCode(); 17257bd2a75ca180cb5da8ba75500163aa06f332caacJean Chalard if (mInputLogic.mCurrentlyPressedHardwareKeys.remove(keyIdentifier)) { 1726976a42b873215a669fe22709960aa1259292d75cJean Chalard return true; 1727976a42b873215a669fe22709960aa1259292d75cJean Chalard } 1728499153734e6dcd01ae9630bf423fadd25628339cTadashi G. Takaoka return super.onKeyUp(keyCode, keyEvent); 1729cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard } 1730cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard 1731cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard // onKeyDown and onKeyUp are the main events we are interested in. There are two more events 1732cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard // related to handling of hardware key events that we may want to implement in the future: 1733cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard // boolean onKeyLongPress(final int keyCode, final KeyEvent event); 1734cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard // boolean onKeyMultiple(final int keyCode, final int count, final KeyEvent event); 1735cff28c5d5db3e0c3e97149519a3f705150aeb224Jean Chalard 17362b25f674f29a4c7b3c8d70bc0fbfbdc60da131c4Tadashi G. Takaoka // receive ringer mode change. 17372b25f674f29a4c7b3c8d70bc0fbfbdc60da131c4Tadashi G. Takaoka private final BroadcastReceiver mRingerModeChangeReceiver = new BroadcastReceiver() { 1738923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project @Override 1739f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka public void onReceive(final Context context, final Intent intent) { 1740123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka final String action = intent.getAction(); 17412b25f674f29a4c7b3c8d70bc0fbfbdc60da131c4Tadashi G. Takaoka if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) { 17426f9105383a56c9ae15e35d3abf19c33d1efe5636Tadashi G. Takaoka AudioAndHapticFeedbackManager.getInstance().onRingerModeChanged(); 1743123c4a38514c003aac50caed7ad3cb6ab8f2515aTadashi G. Takaoka } 1744923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1745923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project }; 1746923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 174793d2ab38577fb3d7c919bc4fd19a769f5c93e654Mohammadinamul Sheik void launchSettings(final String extraEntryValue) { 1748ec4b6e7bb37d2f1794673dc896c14d6b554c6a0aJean Chalard mInputLogic.commitTyped(mSettings.getCurrent(), LastComposedWord.NOT_A_SEPARATOR); 1749ec4b6e7bb37d2f1794673dc896c14d6b554c6a0aJean Chalard requestHideSelf(0); 1750ec4b6e7bb37d2f1794673dc896c14d6b554c6a0aJean Chalard final MainKeyboardView mainKeyboardView = mKeyboardSwitcher.getMainKeyboardView(); 1751ec4b6e7bb37d2f1794673dc896c14d6b554c6a0aJean Chalard if (mainKeyboardView != null) { 1752ec4b6e7bb37d2f1794673dc896c14d6b554c6a0aJean Chalard mainKeyboardView.closing(); 1753ec4b6e7bb37d2f1794673dc896c14d6b554c6a0aJean Chalard } 175476cffec78834a2db525608587eae1a5a7ef998ddTadashi G. Takaoka final Intent intent = new Intent(); 175576cffec78834a2db525608587eae1a5a7ef998ddTadashi G. Takaoka intent.setClass(LatinIME.this, SettingsActivity.class); 175640651c8cf7d4296927f9c49aaa57bcfc7b5372caTadashi G. Takaoka intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 175740651c8cf7d4296927f9c49aaa57bcfc7b5372caTadashi G. Takaoka | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 175840651c8cf7d4296927f9c49aaa57bcfc7b5372caTadashi G. Takaoka | Intent.FLAG_ACTIVITY_CLEAR_TOP); 175976cffec78834a2db525608587eae1a5a7ef998ddTadashi G. Takaoka intent.putExtra(SettingsActivity.EXTRA_SHOW_HOME_AS_UP, false); 176093d2ab38577fb3d7c919bc4fd19a769f5c93e654Mohammadinamul Sheik intent.putExtra(SettingsActivity.EXTRA_ENTRY_KEY, extraEntryValue); 1761923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project startActivity(intent); 1762923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 1763923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 17642fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka private void showSubtypeSelectorAndSettings() { 176585996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final CharSequence title = getString(R.string.english_ime_input_options); 176676cffec78834a2db525608587eae1a5a7ef998ddTadashi G. Takaoka // TODO: Should use new string "Select active input modes". 176776cffec78834a2db525608587eae1a5a7ef998ddTadashi G. Takaoka final CharSequence languageSelectionTitle = getString(R.string.language_selection_title); 176885996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka final CharSequence[] items = new CharSequence[] { 176976cffec78834a2db525608587eae1a5a7ef998ddTadashi G. Takaoka languageSelectionTitle, 177076cffec78834a2db525608587eae1a5a7ef998ddTadashi G. Takaoka getString(ApplicationUtils.getActivityTitleResId(this, SettingsActivity.class)) 177185996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka }; 17725f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka final String imeId = mRichImm.getInputMethodIdOfThisIme(); 17736abc852255072e9c5741a7d8f264bec99b0ce14eTadashi G. Takaoka final OnClickListener listener = new OnClickListener() { 17742fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka @Override 17752fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka public void onClick(DialogInterface di, int position) { 17762fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka di.dismiss(); 17772fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka switch (position) { 177885996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka case 0: 1779298b4240f84344bbcd70b72dfb20806ba93ffd22Tadashi G. Takaoka final Intent intent = IntentUtils.getInputLanguageSelectionIntent( 17805f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka imeId, 17812a659b8aa642b0832fa0ac9a93e0640592fcc239Jean Chalard Intent.FLAG_ACTIVITY_NEW_TASK 17822fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 17832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa | Intent.FLAG_ACTIVITY_CLEAR_TOP); 178476cffec78834a2db525608587eae1a5a7ef998ddTadashi G. Takaoka intent.putExtra(Intent.EXTRA_TITLE, languageSelectionTitle); 17852fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka startActivity(intent); 17862fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka break; 1787aa0458f917bb823efab6245f08c65e8f2f7327acKen Wakasa case 1: 178893d2ab38577fb3d7c919bc4fd19a769f5c93e654Mohammadinamul Sheik launchSettings(SettingsActivity.EXTRA_ENTRY_VALUE_LONG_PRESS_COMMA); 1789aa0458f917bb823efab6245f08c65e8f2f7327acKen Wakasa break; 17902fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } 17912fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } 179285996b472a0ec5fc31e57c52aa46c8c7794689bbTadashi G. Takaoka }; 17939b46ddc1d51fac37f970e108f7d93eb9ea11e1beTadashi G. Takaoka final AlertDialog.Builder builder = new AlertDialog.Builder( 17949b46ddc1d51fac37f970e108f7d93eb9ea11e1beTadashi G. Takaoka DialogUtils.getPlatformDialogThemeContext(this)); 17959b46ddc1d51fac37f970e108f7d93eb9ea11e1beTadashi G. Takaoka builder.setItems(items, listener).setTitle(title); 179630d5ed67d6548a4d7efa6354d41ac9719a4e4488Tadashi G. Takaoka final AlertDialog dialog = builder.create(); 179730d5ed67d6548a4d7efa6354d41ac9719a4e4488Tadashi G. Takaoka dialog.setCancelable(true /* cancelable */); 179830d5ed67d6548a4d7efa6354d41ac9719a4e4488Tadashi G. Takaoka dialog.setCanceledOnTouchOutside(true /* cancelable */); 179930d5ed67d6548a4d7efa6354d41ac9719a4e4488Tadashi G. Takaoka showOptionDialog(dialog); 18002fa21f5854e1565deb139e0bf22719fecc5340bcTadashi G. Takaoka } 1801923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project 1802342e81e7a6cfec8054a8978a9bb84b68e76a01b0Tadashi G. Takaoka // TODO: Move this method out of {@link LatinIME}. 18036abc852255072e9c5741a7d8f264bec99b0ce14eTadashi G. Takaoka private void showOptionDialog(final AlertDialog dialog) { 180427e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka final IBinder windowToken = mKeyboardSwitcher.getMainKeyboardView().getWindowToken(); 180527e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka if (windowToken == null) { 180627e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka return; 180727e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka } 180813d6ecc4c275b9e9c38c7713bb2c69d37f3467f3Tadashi G. Takaoka 180913d6ecc4c275b9e9c38c7713bb2c69d37f3467f3Tadashi G. Takaoka final Window window = dialog.getWindow(); 181013d6ecc4c275b9e9c38c7713bb2c69d37f3467f3Tadashi G. Takaoka final WindowManager.LayoutParams lp = window.getAttributes(); 181113d6ecc4c275b9e9c38c7713bb2c69d37f3467f3Tadashi G. Takaoka lp.token = windowToken; 181213d6ecc4c275b9e9c38c7713bb2c69d37f3467f3Tadashi G. Takaoka lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG; 181313d6ecc4c275b9e9c38c7713bb2c69d37f3467f3Tadashi G. Takaoka window.setAttributes(lp); 181413d6ecc4c275b9e9c38c7713bb2c69d37f3467f3Tadashi G. Takaoka window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM); 181513d6ecc4c275b9e9c38c7713bb2c69d37f3467f3Tadashi G. Takaoka 181613d6ecc4c275b9e9c38c7713bb2c69d37f3467f3Tadashi G. Takaoka mOptionsDialog = dialog; 181713d6ecc4c275b9e9c38c7713bb2c69d37f3467f3Tadashi G. Takaoka dialog.show(); 181813d6ecc4c275b9e9c38c7713bb2c69d37f3467f3Tadashi G. Takaoka } 181913d6ecc4c275b9e9c38c7713bb2c69d37f3467f3Tadashi G. Takaoka 1820abaf5827e7a7f5f6c5d8d98e03e6b9528b0c9351Jean Chalard @UsedForTesting 1821107fb4c476779df16be23e245547253978c197acDan Zivkovic SuggestedWords getSuggestedWordsForTest() { 1822dfbe2bfe089b301819039e9b3a7d2c307e6beac7Jean Chalard // You may not use this method for anything else than debug 1823edaa83bb32e7299b5bba2c42d703701c1e2a3d5bDan Zivkovic return DebugFlags.DEBUG_ENABLED ? mInputLogic.mSuggestedWords : null; 1824abaf5827e7a7f5f6c5d8d98e03e6b9528b0c9351Jean Chalard } 1825abaf5827e7a7f5f6c5d8d98e03e6b9528b0c9351Jean Chalard 18265408fec63a52015af9eefe3042eb1c435912195bJean Chalard // DO NOT USE THIS for any other purpose than testing. This is information private to LatinIME. 18275408fec63a52015af9eefe3042eb1c435912195bJean Chalard @UsedForTesting 1828107fb4c476779df16be23e245547253978c197acDan Zivkovic void waitForLoadingDictionaries(final long timeout, final TimeUnit unit) 18299f1fe87580adc9ca041fc044f88341fa262c82a2Keisuke Kuroyanagi throws InterruptedException { 1830a1035be6d877cafda95b2761f9697474b79deeb8Keisuke Kuroyanagi mDictionaryFacilitator.waitForLoadingDictionariesForTesting(timeout, unit); 18315408fec63a52015af9eefe3042eb1c435912195bJean Chalard } 18325408fec63a52015af9eefe3042eb1c435912195bJean Chalard 1833c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard // DO NOT USE THIS for any other purpose than testing. This can break the keyboard badly. 1834c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard @UsedForTesting 1835107fb4c476779df16be23e245547253978c197acDan Zivkovic void replaceDictionariesForTest(final Locale locale) { 1836adfb262797023c4ca57bb470e547f90c88f638caKeisuke Kuroyanagi final SettingsValues settingsValues = mSettings.getCurrent(); 1837107fb4c476779df16be23e245547253978c197acDan Zivkovic mDictionaryFacilitator.resetDictionaries(this, locale, 1838adfb262797023c4ca57bb470e547f90c88f638caKeisuke Kuroyanagi settingsValues.mUseContactsDict, settingsValues.mUsePersonalizedDicts, 1839bc4ae6bdc0249f9282efea5d1fe7ccfefd6f93b0Jatin Matani false /* forceReloadMainDictionary */, 1840d6a8adcb044dd8b73a1c96776a835b411a978b46Dan Zivkovic settingsValues.mAccount, "", /* dictionaryNamePrefix */ 1841bc4ae6bdc0249f9282efea5d1fe7ccfefd6f93b0Jatin Matani this /* DictionaryInitializationListener */); 1842c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard } 1843c239a34262358e51aedb15f2e315bbe9bcd57c4bJean Chalard 1844d36328cecf3b0c5e7acde7bd5963ea670b8d634fKeisuke Kuroyanagi // DO NOT USE THIS for any other purpose than testing. 1845d36328cecf3b0c5e7acde7bd5963ea670b8d634fKeisuke Kuroyanagi @UsedForTesting 1846107fb4c476779df16be23e245547253978c197acDan Zivkovic void clearPersonalizedDictionariesForTest() { 1847bdd6c995cee664e6cd025235be2d00fc439afb1dDan Zivkovic mDictionaryFacilitator.clearUserHistoryDictionary(this); 1848d36328cecf3b0c5e7acde7bd5963ea670b8d634fKeisuke Kuroyanagi } 1849d36328cecf3b0c5e7acde7bd5963ea670b8d634fKeisuke Kuroyanagi 1850ac20253806180ad302e6bdea681d41bc74ba0722Xiaojun Bi @UsedForTesting 1851107fb4c476779df16be23e245547253978c197acDan Zivkovic List<InputMethodSubtype> getEnabledSubtypesForTest() { 18521fa3e9044f4bb7d1eb62118c94a2223af69c14b0Keisuke Kuroyanagi return (mRichImm != null) ? mRichImm.getMyEnabledInputMethodSubtypeList( 18531fa3e9044f4bb7d1eb62118c94a2223af69c14b0Keisuke Kuroyanagi true /* allowsImplicitlySelectedSubtypes */) : new ArrayList<InputMethodSubtype>(); 1854ac20253806180ad302e6bdea681d41bc74ba0722Xiaojun Bi } 1855ac20253806180ad302e6bdea681d41bc74ba0722Xiaojun Bi 185636c7a62dffb7f5b6728fa0850c1f63aee0f14d80Keisuke Kuroyanagi public void dumpDictionaryForDebug(final String dictName) { 1857ea077349563d704dc3fdecf31a6f9f7f95ce4ad4Jean Chalard if (!mDictionaryFacilitator.isActive()) { 18581c0876dc49eee44170cb86ba3d78e759d5bbd573Jean Chalard resetDictionaryFacilitatorIfNecessary(); 185936c7a62dffb7f5b6728fa0850c1f63aee0f14d80Keisuke Kuroyanagi } 1860a1035be6d877cafda95b2761f9697474b79deeb8Keisuke Kuroyanagi mDictionaryFacilitator.dumpDictionaryForDebug(dictName); 186136c7a62dffb7f5b6728fa0850c1f63aee0f14d80Keisuke Kuroyanagi } 186236c7a62dffb7f5b6728fa0850c1f63aee0f14d80Keisuke Kuroyanagi 186328d765ed901bfd1e736056db1cd807c13ef88c35Jean Chalard public void debugDumpStateAndCrashWithException(final String context) { 18641404c1af850236da4fe4ed3825b70cb228a1da5bJean Chalard final SettingsValues settingsValues = mSettings.getCurrent(); 18651404c1af850236da4fe4ed3825b70cb228a1da5bJean Chalard final StringBuilder s = new StringBuilder(settingsValues.toString()); 18661404c1af850236da4fe4ed3825b70cb228a1da5bJean Chalard s.append("\nAttributes : ").append(settingsValues.mInputAttributes) 186728d765ed901bfd1e736056db1cd807c13ef88c35Jean Chalard .append("\nContext : ").append(context); 186828d765ed901bfd1e736056db1cd807c13ef88c35Jean Chalard throw new RuntimeException(s.toString()); 186928d765ed901bfd1e736056db1cd807c13ef88c35Jean Chalard } 187028d765ed901bfd1e736056db1cd807c13ef88c35Jean Chalard 18717e1f5a2d5a96c74691b3b09fa986efb7161e5a12Tadashi G. Takaoka @Override 1872f035649cb612be8b80892c510bbc137a615719b4Tadashi G. Takaoka protected void dump(final FileDescriptor fd, final PrintWriter fout, final String[] args) { 1873923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project super.dump(fd, fout, args); 1874a16ff1b19e8e012cf37a234bae67b994e805bfb1Doug Zongker 1875923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project final Printer p = new PrintWriterPrinter(fout); 1876923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project p.println("LatinIME state :"); 18772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa p.println(" VersionCode = " + ApplicationUtils.getVersionCode(this)); 18782fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa p.println(" VersionName = " + ApplicationUtils.getVersionName(this)); 18793708787fe91227083d2a1874fa41493d3bc9fe10Tadashi G. Takaoka final Keyboard keyboard = mKeyboardSwitcher.getKeyboard(); 1880df9deffba241d3f1527092212de02f5c77a0b24aTadashi G. Takaoka final int keyboardMode = keyboard != null ? keyboard.mId.mMode : -1; 1881df9deffba241d3f1527092212de02f5c77a0b24aTadashi G. Takaoka p.println(" Keyboard mode = " + keyboardMode); 1882ff0735ada807239abeb4c6105b7d01d2bcea0aedTadashi G. Takaoka final SettingsValues settingsValues = mSettings.getCurrent(); 1883367a35d377076e387a542560f033434959d72d1dJean Chalard p.println(settingsValues.dump()); 1884c809dc26a1e5667de6568ae1ef8c64269f884a4fChieu Nguyen p.println(mDictionaryFacilitator.dump(this /* context */)); 18851404c1af850236da4fe4ed3825b70cb228a1da5bJean Chalard // TODO: Dump all settings values 1886923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project } 18878ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa 18888ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa public boolean shouldSwitchToOtherInputMethods() { 18898ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa // TODO: Revisit here to reorganize the settings. Probably we can/should use different 18908ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa // strategy once the implementation of 18918ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa // {@link InputMethodManager#shouldOfferSwitchingToNextInputMethod} is defined well. 18928ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa final boolean fallbackValue = mSettings.getCurrent().mIncludesOtherImesInLanguageSwitchList; 18938ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa final IBinder token = getWindow().getWindow().getAttributes().token; 18948ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa if (token == null) { 18958ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa return fallbackValue; 18968ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa } 18978ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa return mRichImm.shouldOfferSwitchingToNextInputMethod(token, fallbackValue); 18988ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa } 18998ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa 19008ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa public boolean shouldShowLanguageSwitchKey() { 19018ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa // TODO: Revisit here to reorganize the settings. Probably we can/should use different 19028ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa // strategy once the implementation of 19038ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa // {@link InputMethodManager#shouldOfferSwitchingToNextInputMethod} is defined well. 19048ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa final boolean fallbackValue = mSettings.getCurrent().isLanguageSwitchKeyEnabled(); 19058ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa final IBinder token = getWindow().getWindow().getAttributes().token; 19068ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa if (token == null) { 19078ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa return fallbackValue; 19088ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa } 19098ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa return mRichImm.shouldOfferSwitchingToNextInputMethod(token, fallbackValue); 19108ba4f33709e6c40ade96922f88feace6e4b75b56Yohei Yukawa } 19116c04339c5aadb5118b0e0a8178b3d569956bbad7Seigo Nonaka 19126c04339c5aadb5118b0e0a8178b3d569956bbad7Seigo Nonaka private void setNavigationBarVisibility(final boolean visible) { 191360b59042d1f5a1449de049a7f7adb3d6e40b8b06Yohei Yukawa if (BuildCompatUtils.EFFECTIVE_SDK_INT > Build.VERSION_CODES.M) { 191460b59042d1f5a1449de049a7f7adb3d6e40b8b06Yohei Yukawa // For N and later, IMEs can specify Color.TRANSPARENT to make the navigation bar 191560b59042d1f5a1449de049a7f7adb3d6e40b8b06Yohei Yukawa // transparent. For other colors the system uses the default color. 191660b59042d1f5a1449de049a7f7adb3d6e40b8b06Yohei Yukawa getWindow().getWindow().setNavigationBarColor( 191760b59042d1f5a1449de049a7f7adb3d6e40b8b06Yohei Yukawa visible ? Color.BLACK : Color.TRANSPARENT); 191860b59042d1f5a1449de049a7f7adb3d6e40b8b06Yohei Yukawa } 19196c04339c5aadb5118b0e0a8178b3d569956bbad7Seigo Nonaka } 1920923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project} 1921