1923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/*
2443c360d0afdbab091994244f045f4756feaf2b4Jean-Baptiste Queru * Copyright (C) 2008 The Android Open Source Project
3571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka *
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
7571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka *
88aa9963a895f9dd5bb1bc92ab2e4f461e058f87aTadashi G. Takaoka *      http://www.apache.org/licenses/LICENSE-2.0
9571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaoka *
10923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
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
17571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaokapackage com.android.inputmethod.keyboard;
18923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
19c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaokaimport android.content.Context;
20c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaokaimport android.content.res.Resources;
21c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaokaimport android.util.Log;
2213a741999480343ccebd81ff6349b572bde17b07Tadashi G. Takaokaimport android.view.ContextThemeWrapper;
23c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaokaimport android.view.LayoutInflater;
24c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaokaimport android.view.View;
25c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaokaimport android.view.inputmethod.EditorInfo;
26c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka
27db86a6f271e5ca446382061f219928c5eb6b9f01Tadashi G. Takaokaimport com.android.inputmethod.compat.InputMethodServiceCompatUtils;
28e38043849e01adfb2f6eb33cf6133c1d39d2466aJean Chalardimport com.android.inputmethod.event.Event;
2911d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaokaimport com.android.inputmethod.keyboard.KeyboardLayoutSet.KeyboardLayoutSetException;
309f4d62cc42ab66f72ecb23996ffc2f8b039c8c4aTadashi G. Takaokaimport com.android.inputmethod.keyboard.emoji.EmojiPalettesView;
31b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaokaimport com.android.inputmethod.keyboard.internal.KeyboardState;
32d227b00a72a68c59b8d2b2243a68c0f59d919b25Tadashi G. Takaokaimport com.android.inputmethod.keyboard.internal.KeyboardTextsSet;
33f451ed2012df7eb080de045a93a494aecd2775b4Tadashi G. Takaokaimport com.android.inputmethod.latin.InputView;
34571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaokaimport com.android.inputmethod.latin.LatinIME;
35571bdb401f670b92bd7710a12a990cb65a99b7d3Tadashi G. Takaokaimport com.android.inputmethod.latin.R;
366fbbab3b8442ad010c53dc53a09535f7b0ef0323Tadashi G. Takaokaimport com.android.inputmethod.latin.RichInputMethodManager;
37adbd9ae105e06287b59379d7f7127d95fd0663f4Jean Chalardimport com.android.inputmethod.latin.WordComposer;
38081c2d386dbd792162e1296ea0c561ffd4fa1739Sandeep Siddharthaimport com.android.inputmethod.latin.define.ProductionFlags;
396bb6d30344259b41387f15f0e05df2388beb1d1cJean Chalardimport com.android.inputmethod.latin.settings.Settings;
40a7d2fc6befa1b16883200a653fc01deb4d94944dKen Wakasaimport com.android.inputmethod.latin.settings.SettingsValues;
41c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaokaimport com.android.inputmethod.latin.utils.CapsModeUtils;
424934a88b618f06600e2d725a43bdd2511715b4caTadashi G. Takaokaimport com.android.inputmethod.latin.utils.LanguageOnSpacebarUtils;
43c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaokaimport com.android.inputmethod.latin.utils.RecapitalizeStatus;
443897a43940eca9c400e542c76d2c790f2c48eb8cTadashi G. Takaokaimport com.android.inputmethod.latin.utils.ResourceUtils;
455f6c303f0ba70c0bcfd73d06b63f0175669dafc1Jean Chalardimport com.android.inputmethod.latin.utils.ScriptUtils;
465a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaoka
471fdb8f31562eeef78167585a878eb0450310036bDan Zivkovicimport javax.annotation.Nonnull;
481fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic
4912d80ebead6a1d7f704a5a3af3b6fe3313ceab05Dan Zivkovicpublic final class KeyboardSwitcher implements KeyboardState.SwitchActions {
50c25e07d21261583d0eeca5aa0fb6e3ffe93dc603Tadashi G. Takaoka    private static final String TAG = KeyboardSwitcher.class.getSimpleName();
51923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
52f451ed2012df7eb080de045a93a494aecd2775b4Tadashi G. Takaoka    private InputView mCurrentInputView;
535169937dd48d69e52e647662cb6fc3def5bf90d4Satoshi Kataoka    private View mMainKeyboardFrame;
54c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka    private MainKeyboardView mKeyboardView;
55d76b55297940a65bb9479020a9ed58aa978a0aeaSatoshi Kataoka    private EmojiPalettesView mEmojiPalettesView;
5616950d65c323f99507d97cb7f0403dc653e2506cTadashi G. Takaoka    private LatinIME mLatinIME;
574934a88b618f06600e2d725a43bdd2511715b4caTadashi G. Takaoka    private RichInputMethodManager mRichImm;
58db86a6f271e5ca446382061f219928c5eb6b9f01Tadashi G. Takaoka    private boolean mIsHardwareAcceleratedDrawingEnabled;
5931adfa78e2edae188edb05e869f9f68798857582satok
60b88c9acd88348c160e3d114593660bfd362bee29Tadashi G. Takaoka    private KeyboardState mState;
61889691eca1ad991a85fb721deb37ecba6a913762Tadashi G. Takaoka
6211d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka    private KeyboardLayoutSet mKeyboardLayoutSet;
63d227b00a72a68c59b8d2b2243a68c0f59d919b25Tadashi G. Takaoka    // TODO: The following {@link KeyboardTextsSet} should be in {@link KeyboardLayoutSet}.
64d227b00a72a68c59b8d2b2243a68c0f59d919b25Tadashi G. Takaoka    private final KeyboardTextsSet mKeyboardTextsSet = new KeyboardTextsSet();
65353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger
6659c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka    private KeyboardTheme mKeyboardTheme;
675a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka    private Context mThemeContext;
68be819dbe2b7a5c418530a2fa1182766a4d31d6d5Tadashi G. Takaoka
690ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok    private static final KeyboardSwitcher sInstance = new KeyboardSwitcher();
700ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok
710ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok    public static KeyboardSwitcher getInstance() {
720ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok        return sInstance;
730ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok    }
740ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok
750ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok    private KeyboardSwitcher() {
76e26ef1bccddc942fdaeada3409c8e8ff18a35008Tadashi G. Takaoka        // Intentional empty constructor for singleton.
770ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok    }
780ed7191b4d1013a0b9d2fd1f26733dee7364871dsatok
79f90fc105ab1159f43f536bcacdd1224c2c05bacbTadashi G. Takaoka    public static void init(final LatinIME latinIme) {
80311f12d0248f780f901bd76b6cb4e8f8960ce963Tadashi G. Takaoka        sInstance.initInternal(latinIme);
81364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka    }
82364f1fd1f84cca6c8d396064bfd8bc8fd1efefcbTadashi G. Takaoka
83311f12d0248f780f901bd76b6cb4e8f8960ce963Tadashi G. Takaoka    private void initInternal(final LatinIME latinIme) {
8416950d65c323f99507d97cb7f0403dc653e2506cTadashi G. Takaoka        mLatinIME = latinIme;
854934a88b618f06600e2d725a43bdd2511715b4caTadashi G. Takaoka        mRichImm = RichInputMethodManager.getInstance();
86eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka        mState = new KeyboardState(this);
87db86a6f271e5ca446382061f219928c5eb6b9f01Tadashi G. Takaoka        mIsHardwareAcceleratedDrawingEnabled =
88db86a6f271e5ca446382061f219928c5eb6b9f01Tadashi G. Takaoka                InputMethodServiceCompatUtils.enableHardwareAcceleration(mLatinIME);
89db86a6f271e5ca446382061f219928c5eb6b9f01Tadashi G. Takaoka    }
90db86a6f271e5ca446382061f219928c5eb6b9f01Tadashi G. Takaoka
91db86a6f271e5ca446382061f219928c5eb6b9f01Tadashi G. Takaoka    public void updateKeyboardTheme() {
92db86a6f271e5ca446382061f219928c5eb6b9f01Tadashi G. Takaoka        final boolean themeUpdated = updateKeyboardThemeAndContextThemeWrapper(
93311f12d0248f780f901bd76b6cb4e8f8960ce963Tadashi G. Takaoka                mLatinIME, KeyboardTheme.getKeyboardTheme(mLatinIME /* context */));
94db86a6f271e5ca446382061f219928c5eb6b9f01Tadashi G. Takaoka        if (themeUpdated && mKeyboardView != null) {
95db86a6f271e5ca446382061f219928c5eb6b9f01Tadashi G. Takaoka            mLatinIME.setInputView(onCreateInputView(mIsHardwareAcceleratedDrawingEnabled));
96db86a6f271e5ca446382061f219928c5eb6b9f01Tadashi G. Takaoka        }
975a2d0630474d6df639e97ff48f5f48b220ca4ee9Tadashi G. Takaoka    }
98979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
99db86a6f271e5ca446382061f219928c5eb6b9f01Tadashi G. Takaoka    private boolean updateKeyboardThemeAndContextThemeWrapper(final Context context,
100db86a6f271e5ca446382061f219928c5eb6b9f01Tadashi G. Takaoka            final KeyboardTheme keyboardTheme) {
10159c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka        if (mThemeContext == null || !keyboardTheme.equals(mKeyboardTheme)) {
102411749a4baddc0fda7720deb6e4d67c1f1558cc5Tadashi G. Takaoka            mKeyboardTheme = keyboardTheme;
103411749a4baddc0fda7720deb6e4d67c1f1558cc5Tadashi G. Takaoka            mThemeContext = new ContextThemeWrapper(context, keyboardTheme.mStyleId);
104f2eadbb497a172f602e49226a7f891d9e9097760Tadashi G. Takaoka            KeyboardLayoutSet.onKeyboardThemeChanged();
105db86a6f271e5ca446382061f219928c5eb6b9f01Tadashi G. Takaoka            return true;
10605ddb9a5d2b36f519a4de4b50448e258f40d2c0fTadashi G. Takaoka        }
107db86a6f271e5ca446382061f219928c5eb6b9f01Tadashi G. Takaoka        return false;
108979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    }
109979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
110f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard    public void loadKeyboard(final EditorInfo editorInfo, final SettingsValues settingsValues,
111f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard            final int currentAutoCapsState, final int currentRecapitalizeState) {
11211d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka        final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(
11311d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka                mThemeContext, editorInfo);
1144731b67629e72d6c7cb391e3d188df78ceaff1e7Tadashi G. Takaoka        final Resources res = mThemeContext.getResources();
115be819dbe2b7a5c418530a2fa1182766a4d31d6d5Tadashi G. Takaoka        final int keyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res);
116bb9400aebc4cb0291b4f0208ecbc9ddc01dc79e1Andy Wang        final int keyboardHeight = ResourceUtils.getKeyboardHeight(res, settingsValues);
1173897a43940eca9c400e542c76d2c790f2c48eb8cTadashi G. Takaoka        builder.setKeyboardGeometry(keyboardWidth, keyboardHeight);
1184934a88b618f06600e2d725a43bdd2511715b4caTadashi G. Takaoka        builder.setSubtype(mRichImm.getCurrentSubtype());
119aa4b2c71270576f25e7c80a4b63a1956cec5f4e2Tadashi G. Takaoka        builder.setVoiceInputKeyEnabled(settingsValues.mShowsVoiceInputKey);
1203ca65c8fd56724a7b4b3440bccf613e5a1a17513Tadashi G. Takaoka        builder.setLanguageSwitchKeyEnabled(mLatinIME.shouldShowLanguageSwitchKey());
121081c2d386dbd792162e1296ea0c561ffd4fa1739Sandeep Siddhartha        builder.setSplitLayoutEnabledByUser(ProductionFlags.IS_SPLIT_KEYBOARD_SUPPORTED
122081c2d386dbd792162e1296ea0c561ffd4fa1739Sandeep Siddhartha                && settingsValues.mIsSplitKeyboardEnabled);
12311d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka        mKeyboardLayoutSet = builder.build();
124979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        try {
125f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard            mState.onLoadKeyboard(currentAutoCapsState, currentRecapitalizeState);
126107fb4c476779df16be23e245547253978c197acDan Zivkovic            mKeyboardTextsSet.setLocale(mRichImm.getCurrentSubtypeLocale(), mThemeContext);
12711d9ee742f8ff3fb31b0e3beb32ee4870c63d8e3Tadashi G. Takaoka        } catch (KeyboardLayoutSetException e) {
12888e079ae6bbff1093b28f60e81d2befce1030495Tadashi G. Takaoka            Log.w(TAG, "loading keyboard failed: " + e.mKeyboardId, e.getCause());
129645128af712961456a42cbcc34c0cdf5f0b40a83Tadashi G. Takaoka        }
130353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger    }
131353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger
13259f8ca752d5f79d4469519623590052c050c9d23Tadashi G. Takaoka    public void saveKeyboardState() {
1336fc15b9fc43c791e1fc96e1d5e812ed2e14995eaJean Chalard        if (getKeyboard() != null || isShowingEmojiPalettes()) {
13410dcc7eb672a561a1d9f510f4d2109dcab251e36Tadashi G. Takaoka            mState.onSaveKeyboardState();
1352e263b70d5769b52cba4a002e44dbf81db5de7f8Tadashi G. Takaoka        }
136055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka    }
137055054eef3ccd32c6dfd69a3f76bfb7383ea93bbTadashi G. Takaoka
138c3d175c01ff1956ddb1c2d608d69af1793b4ad8aTadashi G. Takaoka    public void onHideWindow() {
1390de529b4cac458b2d561060d3ae2c7f7f82b676dKen Wakasa        if (mKeyboardView != null) {
1400de529b4cac458b2d561060d3ae2c7f7f82b676dKen Wakasa            mKeyboardView.onHideWindow();
1410de529b4cac458b2d561060d3ae2c7f7f82b676dKen Wakasa        }
142c3d175c01ff1956ddb1c2d608d69af1793b4ad8aTadashi G. Takaoka    }
143c3d175c01ff1956ddb1c2d608d69af1793b4ad8aTadashi G. Takaoka
1441fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic    private void setKeyboard(
1451fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            @Nonnull final int keyboardId,
1461fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            @Nonnull final KeyboardSwitchState toggleState) {
147d76b55297940a65bb9479020a9ed58aa978a0aeaSatoshi Kataoka        // Make {@link MainKeyboardView} visible and hide {@link EmojiPalettesView}.
1486bb6d30344259b41387f15f0e05df2388beb1d1cJean Chalard        final SettingsValues currentSettingsValues = Settings.getInstance().getCurrent();
1491fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        setMainKeyboardFrame(currentSettingsValues, toggleState);
1506bb6d30344259b41387f15f0e05df2388beb1d1cJean Chalard        // TODO: pass this object to setKeyboard instead of getting the current values.
1510657b9698a110f8e895448d829478982ce37b6d1Tadashi G. Takaoka        final MainKeyboardView keyboardView = mKeyboardView;
1520657b9698a110f8e895448d829478982ce37b6d1Tadashi G. Takaoka        final Keyboard oldKeyboard = keyboardView.getKeyboard();
1531fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        final Keyboard newKeyboard = mKeyboardLayoutSet.getKeyboard(keyboardId);
1541fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        keyboardView.setKeyboard(newKeyboard);
1551fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        mCurrentInputView.setKeyboardTopPadding(newKeyboard.mTopPadding);
1560657b9698a110f8e895448d829478982ce37b6d1Tadashi G. Takaoka        keyboardView.setKeyPreviewPopupEnabled(
1576bb6d30344259b41387f15f0e05df2388beb1d1cJean Chalard                currentSettingsValues.mKeyPreviewPopupOn,
1586bb6d30344259b41387f15f0e05df2388beb1d1cJean Chalard                currentSettingsValues.mKeyPreviewPopupDismissDelay);
159276b1a2ebc6d5ea3fa36fa9271cdc6310db34021Tadashi G. Takaoka        keyboardView.setKeyPreviewAnimationParams(
1606bb6d30344259b41387f15f0e05df2388beb1d1cJean Chalard                currentSettingsValues.mHasCustomKeyPreviewAnimationParams,
1616bb6d30344259b41387f15f0e05df2388beb1d1cJean Chalard                currentSettingsValues.mKeyPreviewShowUpStartXScale,
1626bb6d30344259b41387f15f0e05df2388beb1d1cJean Chalard                currentSettingsValues.mKeyPreviewShowUpStartYScale,
1636bb6d30344259b41387f15f0e05df2388beb1d1cJean Chalard                currentSettingsValues.mKeyPreviewShowUpDuration,
1646bb6d30344259b41387f15f0e05df2388beb1d1cJean Chalard                currentSettingsValues.mKeyPreviewDismissEndXScale,
1656bb6d30344259b41387f15f0e05df2388beb1d1cJean Chalard                currentSettingsValues.mKeyPreviewDismissEndYScale,
1666bb6d30344259b41387f15f0e05df2388beb1d1cJean Chalard                currentSettingsValues.mKeyPreviewDismissDuration);
1674934a88b618f06600e2d725a43bdd2511715b4caTadashi G. Takaoka        keyboardView.updateShortcutKey(mRichImm.isShortcutImeReady());
168dabf96896ef4c304c6dad36b307a2a458a58209dTadashi G. Takaoka        final boolean subtypeChanged = (oldKeyboard == null)
1691fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic                || !newKeyboard.mId.mSubtype.equals(oldKeyboard.mId.mSubtype);
1704934a88b618f06600e2d725a43bdd2511715b4caTadashi G. Takaoka        final int languageOnSpacebarFormatType = LanguageOnSpacebarUtils
1711fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic                .getLanguageOnSpacebarFormatType(newKeyboard.mId.mSubtype);
1724934a88b618f06600e2d725a43bdd2511715b4caTadashi G. Takaoka        final boolean hasMultipleEnabledIMEsOrSubtypes = mRichImm
1737dd32dfc065c13e946c0d42a0e000f4ce7298ed7Tadashi G. Takaoka                .hasMultipleEnabledIMEsOrSubtypes(true /* shouldIncludeAuxiliarySubtypes */);
1747dd32dfc065c13e946c0d42a0e000f4ce7298ed7Tadashi G. Takaoka        keyboardView.startDisplayLanguageOnSpacebar(subtypeChanged, languageOnSpacebarFormatType,
1757dd32dfc065c13e946c0d42a0e000f4ce7298ed7Tadashi G. Takaoka                hasMultipleEnabledIMEsOrSubtypes);
176353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger    }
177353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger
1783708787fe91227083d2a1874fa41493d3bc9fe10Tadashi G. Takaoka    public Keyboard getKeyboard() {
179c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka        if (mKeyboardView != null) {
1803708787fe91227083d2a1874fa41493d3bc9fe10Tadashi G. Takaoka            return mKeyboardView.getKeyboard();
181050c0462dc2ada5a5afecec5b6745693c5066b85Tadashi G. Takaoka        }
182b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka        return null;
1831679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka    }
1841679432d1c8a8cfe6ff09be0a49792f4af91ab35Tadashi G. Takaoka
1855d2556b93286f5f1d7d829b586b84a8b7ae55743Ken Wakasa    // TODO: Remove this method. Come up with a more comprehensive way to reset the keyboard layout
1865d2556b93286f5f1d7d829b586b84a8b7ae55743Ken Wakasa    // when a keyboard layout set doesn't get reloaded in LatinIME.onStartInputViewInternal().
187f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard    public void resetKeyboardStateToAlphabet(final int currentAutoCapsState,
188f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard            final int currentRecapitalizeState) {
189f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard        mState.onResetKeyboardStateToAlphabet(currentAutoCapsState, currentRecapitalizeState);
1905d2556b93286f5f1d7d829b586b84a8b7ae55743Ken Wakasa    }
1915d2556b93286f5f1d7d829b586b84a8b7ae55743Ken Wakasa
1929320553ab922621f021a66f934ae9b40c8da21b8Jean Chalard    public void onPressKey(final int code, final boolean isSinglePointer,
193f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard            final int currentAutoCapsState, final int currentRecapitalizeState) {
194f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard        mState.onPressKey(code, isSinglePointer, currentAutoCapsState, currentRecapitalizeState);
1950f05076990f1308c34c2f12ed793e1e1c41f8ac1Tadashi G. Takaoka    }
1960f05076990f1308c34c2f12ed793e1e1c41f8ac1Tadashi G. Takaoka
197ddc163988a7e2e910ff3cac26ed580bac123fda0Jean Chalard    public void onReleaseKey(final int code, final boolean withSliding,
198ddc163988a7e2e910ff3cac26ed580bac123fda0Jean Chalard            final int currentAutoCapsState, final int currentRecapitalizeState) {
199ddc163988a7e2e910ff3cac26ed580bac123fda0Jean Chalard        mState.onReleaseKey(code, withSliding, currentAutoCapsState, currentRecapitalizeState);
2000f05076990f1308c34c2f12ed793e1e1c41f8ac1Tadashi G. Takaoka    }
2010f05076990f1308c34c2f12ed793e1e1c41f8ac1Tadashi G. Takaoka
202f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard    public void onFinishSlidingInput(final int currentAutoCapsState,
203f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard            final int currentRecapitalizeState) {
204f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard        mState.onFinishSlidingInput(currentAutoCapsState, currentRecapitalizeState);
2050f05076990f1308c34c2f12ed793e1e1c41f8ac1Tadashi G. Takaoka    }
2060f05076990f1308c34c2f12ed793e1e1c41f8ac1Tadashi G. Takaoka
2070f05076990f1308c34c2f12ed793e1e1c41f8ac1Tadashi G. Takaoka    // Implements {@link KeyboardState.SwitchActions}.
2080f05076990f1308c34c2f12ed793e1e1c41f8ac1Tadashi G. Takaoka    @Override
2090f05076990f1308c34c2f12ed793e1e1c41f8ac1Tadashi G. Takaoka    public void setAlphabetKeyboard() {
210c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        if (DEBUG_ACTION) {
211c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka            Log.d(TAG, "setAlphabetKeyboard");
212c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        }
2131fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        setKeyboard(KeyboardId.ELEMENT_ALPHABET, KeyboardSwitchState.OTHER);
214b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka    }
215b643dab73ab9527cc63d896cad81c0cdc92fe5f6Tadashi G. Takaoka
2160f05076990f1308c34c2f12ed793e1e1c41f8ac1Tadashi G. Takaoka    // Implements {@link KeyboardState.SwitchActions}.
2170f05076990f1308c34c2f12ed793e1e1c41f8ac1Tadashi G. Takaoka    @Override
2180f05076990f1308c34c2f12ed793e1e1c41f8ac1Tadashi G. Takaoka    public void setAlphabetManualShiftedKeyboard() {
219c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        if (DEBUG_ACTION) {
220c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka            Log.d(TAG, "setAlphabetManualShiftedKeyboard");
221c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        }
2221fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        setKeyboard(KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED, KeyboardSwitchState.OTHER);
2236c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka    }
2246c92ee127df50509d364a2b6d428b223d2cbaa6eTadashi G. Takaoka
2250f05076990f1308c34c2f12ed793e1e1c41f8ac1Tadashi G. Takaoka    // Implements {@link KeyboardState.SwitchActions}.
2260f05076990f1308c34c2f12ed793e1e1c41f8ac1Tadashi G. Takaoka    @Override
2270f05076990f1308c34c2f12ed793e1e1c41f8ac1Tadashi G. Takaoka    public void setAlphabetAutomaticShiftedKeyboard() {
228c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        if (DEBUG_ACTION) {
229c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka            Log.d(TAG, "setAlphabetAutomaticShiftedKeyboard");
230c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        }
2311fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        setKeyboard(KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED, KeyboardSwitchState.OTHER);
2325f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka    }
2335f922caff80d5067c5af2bbbae2731ef25c9572aTadashi G. Takaoka
234eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka    // Implements {@link KeyboardState.SwitchActions}.
235eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka    @Override
2360f05076990f1308c34c2f12ed793e1e1c41f8ac1Tadashi G. Takaoka    public void setAlphabetShiftLockedKeyboard() {
237c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        if (DEBUG_ACTION) {
238c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka            Log.d(TAG, "setAlphabetShiftLockedKeyboard");
239c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        }
2401fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        setKeyboard(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED, KeyboardSwitchState.OTHER);
2418a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka    }
2428a70e70c849cc2c5553c6fd79891c22893fd761bTadashi G. Takaoka
243eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka    // Implements {@link KeyboardState.SwitchActions}.
244eef6238f94b5046054d9ae9c06f775362893c0eeTadashi G. Takaoka    @Override
245757f8d96eea3dfb5951243d2ebb4b763db868471Tadashi G. Takaoka    public void setAlphabetShiftLockShiftedKeyboard() {
246c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        if (DEBUG_ACTION) {
247c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka            Log.d(TAG, "setAlphabetShiftLockShiftedKeyboard");
248c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        }
2491fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        setKeyboard(KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED, KeyboardSwitchState.OTHER);
250757f8d96eea3dfb5951243d2ebb4b763db868471Tadashi G. Takaoka    }
251757f8d96eea3dfb5951243d2ebb4b763db868471Tadashi G. Takaoka
252757f8d96eea3dfb5951243d2ebb4b763db868471Tadashi G. Takaoka    // Implements {@link KeyboardState.SwitchActions}.
253757f8d96eea3dfb5951243d2ebb4b763db868471Tadashi G. Takaoka    @Override
2540f05076990f1308c34c2f12ed793e1e1c41f8ac1Tadashi G. Takaoka    public void setSymbolsKeyboard() {
255c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        if (DEBUG_ACTION) {
256c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka            Log.d(TAG, "setSymbolsKeyboard");
257c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        }
2581fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        setKeyboard(KeyboardId.ELEMENT_SYMBOLS, KeyboardSwitchState.OTHER);
2591fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic    }
2601fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic
2611fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic    // Implements {@link KeyboardState.SwitchActions}.
2621fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic    @Override
2631fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic    public void setSymbolsShiftedKeyboard() {
2641fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        if (DEBUG_ACTION) {
2651fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            Log.d(TAG, "setSymbolsShiftedKeyboard");
2661fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        }
2671fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        setKeyboard(KeyboardId.ELEMENT_SYMBOLS_SHIFTED, KeyboardSwitchState.SYMBOLS_SHIFTED);
26846831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka    }
26946831d5a4b135e5c21f2212d1d8aef09806800edTadashi G. Takaoka
2701fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic    public boolean isImeSuppressedByHardwareKeyboard(
2711fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            @Nonnull final SettingsValues settingsValues,
2721fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            @Nonnull final KeyboardSwitchState toggleState) {
2731fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        return settingsValues.mHasHardwareKeyboard && toggleState == KeyboardSwitchState.HIDDEN;
2741fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic    }
2751fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic
2761fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic    private void setMainKeyboardFrame(
2771fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            @Nonnull final SettingsValues settingsValues,
2781fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            @Nonnull final KeyboardSwitchState toggleState) {
2791fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        final int visibility =  isImeSuppressedByHardwareKeyboard(settingsValues, toggleState)
2801fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic                ? View.GONE : View.VISIBLE;
28198dfa6e3346b95f3da8869048715e2e18f85d65eTadashi G. Takaoka        mKeyboardView.setVisibility(visibility);
28298dfa6e3346b95f3da8869048715e2e18f85d65eTadashi G. Takaoka        // The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}.
28398dfa6e3346b95f3da8869048715e2e18f85d65eTadashi G. Takaoka        // @see #getVisibleKeyboardView() and
28498dfa6e3346b95f3da8869048715e2e18f85d65eTadashi G. Takaoka        // @see LatinIME#onComputeInset(android.inputmethodservice.InputMethodService.Insets)
28598dfa6e3346b95f3da8869048715e2e18f85d65eTadashi G. Takaoka        mMainKeyboardFrame.setVisibility(visibility);
286d76b55297940a65bb9479020a9ed58aa978a0aeaSatoshi Kataoka        mEmojiPalettesView.setVisibility(View.GONE);
2870e01df9baf3d9e2fc7b9a51b683ce6df6ff547ddSatoshi Kataoka        mEmojiPalettesView.stopEmojiPalettes();
2885169937dd48d69e52e647662cb6fc3def5bf90d4Satoshi Kataoka    }
2895169937dd48d69e52e647662cb6fc3def5bf90d4Satoshi Kataoka
2905169937dd48d69e52e647662cb6fc3def5bf90d4Satoshi Kataoka    // Implements {@link KeyboardState.SwitchActions}.
2915169937dd48d69e52e647662cb6fc3def5bf90d4Satoshi Kataoka    @Override
2925169937dd48d69e52e647662cb6fc3def5bf90d4Satoshi Kataoka    public void setEmojiKeyboard() {
293c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        if (DEBUG_ACTION) {
294c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka            Log.d(TAG, "setEmojiKeyboard");
295c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        }
296afdcc15ca8ea75f4c5a22d7d25eb5e253bdf1c7fTadashi G. Takaoka        final Keyboard keyboard = mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET);
2975169937dd48d69e52e647662cb6fc3def5bf90d4Satoshi Kataoka        mMainKeyboardFrame.setVisibility(View.GONE);
29898dfa6e3346b95f3da8869048715e2e18f85d65eTadashi G. Takaoka        // The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}.
29998dfa6e3346b95f3da8869048715e2e18f85d65eTadashi G. Takaoka        // @see #getVisibleKeyboardView() and
30098dfa6e3346b95f3da8869048715e2e18f85d65eTadashi G. Takaoka        // @see LatinIME#onComputeInset(android.inputmethodservice.InputMethodService.Insets)
30198dfa6e3346b95f3da8869048715e2e18f85d65eTadashi G. Takaoka        mKeyboardView.setVisibility(View.GONE);
302fe39aec08a295ff6bd4622207ebacdbaa746c300Tadashi G. Takaoka        mEmojiPalettesView.startEmojiPalettes(
303d227b00a72a68c59b8d2b2243a68c0f59d919b25Tadashi G. Takaoka                mKeyboardTextsSet.getText(KeyboardTextsSet.SWITCH_TO_ALPHA_KEY_LABEL),
304c1094d69134740ee0209f1ddfb25dd770b37ab25Tadashi G. Takaoka                mKeyboardView.getKeyVisualAttribute(), keyboard.mIconsSet);
305d76b55297940a65bb9479020a9ed58aa978a0aeaSatoshi Kataoka        mEmojiPalettesView.setVisibility(View.VISIBLE);
3065169937dd48d69e52e647662cb6fc3def5bf90d4Satoshi Kataoka    }
3075169937dd48d69e52e647662cb6fc3def5bf90d4Satoshi Kataoka
3081fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic    public enum KeyboardSwitchState {
3091fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        HIDDEN(-1),
3101fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        SYMBOLS_SHIFTED(KeyboardId.ELEMENT_SYMBOLS_SHIFTED),
3111fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        EMOJI(KeyboardId.ELEMENT_EMOJI_RECENTS),
3121fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        OTHER(-1);
3131fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic
3141fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        final int mKeyboardId;
3151fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic
3161fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        KeyboardSwitchState(int keyboardId) {
3171fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            mKeyboardId = keyboardId;
3188fdff5a11129827e88ce9f5bc462e18f613c19a3Tadashi G. Takaoka        }
3198fdff5a11129827e88ce9f5bc462e18f613c19a3Tadashi G. Takaoka    }
3208fdff5a11129827e88ce9f5bc462e18f613c19a3Tadashi G. Takaoka
3211fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic    public KeyboardSwitchState getKeyboardSwitchState() {
3221fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        boolean hidden = !isShowingEmojiPalettes()
3231fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic                && (mKeyboardLayoutSet == null
3241fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic                || mKeyboardView == null
3251fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic                || !mKeyboardView.isShown());
3261fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        KeyboardSwitchState state;
3271fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        if (hidden) {
3281fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            return KeyboardSwitchState.HIDDEN;
3291fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        } else if (isShowingEmojiPalettes()) {
3301fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            return KeyboardSwitchState.EMOJI;
3311fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        } else if (isShowingKeyboardId(KeyboardId.ELEMENT_SYMBOLS_SHIFTED)) {
3321fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            return KeyboardSwitchState.SYMBOLS_SHIFTED;
3331fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        }
3341fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        return KeyboardSwitchState.OTHER;
3351fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic    }
3361fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic
3371fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic    public void onToggleKeyboard(@Nonnull final KeyboardSwitchState toggleState) {
3381fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        KeyboardSwitchState currentState = getKeyboardSwitchState();
3391fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        Log.w(TAG, "onToggleKeyboard() : Current = " + currentState + " : Toggle = " + toggleState);
3401fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        if (currentState == toggleState) {
3411fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            mLatinIME.stopShowingInputView();
3421fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            mLatinIME.hideWindow();
3431fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            setAlphabetKeyboard();
3441fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        } else {
3451fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            mLatinIME.startShowingInputView(true);
3461fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            if (toggleState == KeyboardSwitchState.EMOJI) {
3471fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic                setEmojiKeyboard();
3481fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            } else {
3491fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic                mEmojiPalettesView.stopEmojiPalettes();
3501fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic                mEmojiPalettesView.setVisibility(View.GONE);
3511fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic
3521fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic                mMainKeyboardFrame.setVisibility(View.VISIBLE);
3531fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic                mKeyboardView.setVisibility(View.VISIBLE);
3541fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic                setKeyboard(toggleState.mKeyboardId, toggleState);
3551fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            }
356c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        }
357e3150664ae4d8d007b8571b5bd0fd2259aac3a20Satoshi Kataoka    }
358e3150664ae4d8d007b8571b5bd0fd2259aac3a20Satoshi Kataoka
3598ab4ae4377fca97cb9ef05c615c5a59bc4bc3d8cJean Chalard    // Future method for requesting an updating to the shift state.
3605f00fe09e9a611b647592188316e5999465df4d3Tadashi G. Takaoka    @Override
361c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka    public void requestUpdatingShiftState(final int autoCapsFlags, final int recapitalizeMode) {
362c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        if (DEBUG_ACTION) {
363c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka            Log.d(TAG, "requestUpdatingShiftState: "
364c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka                    + " autoCapsFlags=" + CapsModeUtils.flagsToString(autoCapsFlags)
365c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka                    + " recapitalizeMode=" + RecapitalizeStatus.modeToString(recapitalizeMode));
366c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        }
367c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        mState.onUpdateShiftState(autoCapsFlags, recapitalizeMode);
3688ab4ae4377fca97cb9ef05c615c5a59bc4bc3d8cJean Chalard    }
3698ab4ae4377fca97cb9ef05c615c5a59bc4bc3d8cJean Chalard
3700ed2d3a4491cb0f6142975a15b653be6079b6a4eTadashi G. Takaoka    // Implements {@link KeyboardState.SwitchActions}.
3710ed2d3a4491cb0f6142975a15b653be6079b6a4eTadashi G. Takaoka    @Override
3722a9882a433e2372ac32fbc0def578d4d9a97a676Tadashi G. Takaoka    public void startDoubleTapShiftKeyTimer() {
373c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        if (DEBUG_TIMER_ACTION) {
374c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka            Log.d(TAG, "startDoubleTapShiftKeyTimer");
375c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        }
37627e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka        final MainKeyboardView keyboardView = getMainKeyboardView();
3770ed2d3a4491cb0f6142975a15b653be6079b6a4eTadashi G. Takaoka        if (keyboardView != null) {
3785433ce64c0f141bc4ee82912844f47f575654af5Tadashi G. Takaoka            keyboardView.startDoubleTapShiftKeyTimer();
3790ed2d3a4491cb0f6142975a15b653be6079b6a4eTadashi G. Takaoka        }
3800ed2d3a4491cb0f6142975a15b653be6079b6a4eTadashi G. Takaoka    }
3810ed2d3a4491cb0f6142975a15b653be6079b6a4eTadashi G. Takaoka
3820ed2d3a4491cb0f6142975a15b653be6079b6a4eTadashi G. Takaoka    // Implements {@link KeyboardState.SwitchActions}.
3830ed2d3a4491cb0f6142975a15b653be6079b6a4eTadashi G. Takaoka    @Override
3842a9882a433e2372ac32fbc0def578d4d9a97a676Tadashi G. Takaoka    public void cancelDoubleTapShiftKeyTimer() {
385c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        if (DEBUG_TIMER_ACTION) {
386c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka            Log.d(TAG, "setAlphabetKeyboard");
387c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        }
38827e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka        final MainKeyboardView keyboardView = getMainKeyboardView();
389beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka        if (keyboardView != null) {
3905433ce64c0f141bc4ee82912844f47f575654af5Tadashi G. Takaoka            keyboardView.cancelDoubleTapShiftKeyTimer();
391beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka        }
392beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka    }
393beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka
394beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka    // Implements {@link KeyboardState.SwitchActions}.
395beb08b398fa73a26f2d42d6feec87e34a96ca2d9Tadashi G. Takaoka    @Override
3962a9882a433e2372ac32fbc0def578d4d9a97a676Tadashi G. Takaoka    public boolean isInDoubleTapShiftKeyTimeout() {
397c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        if (DEBUG_TIMER_ACTION) {
398c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka            Log.d(TAG, "isInDoubleTapShiftKeyTimeout");
399c235a3be9dc6bdc9af869f98136462b860928839Tadashi G. Takaoka        }
40027e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka        final MainKeyboardView keyboardView = getMainKeyboardView();
4015433ce64c0f141bc4ee82912844f47f575654af5Tadashi G. Takaoka        return keyboardView != null && keyboardView.isInDoubleTapShiftKeyTimeout();
4020ed2d3a4491cb0f6142975a15b653be6079b6a4eTadashi G. Takaoka    }
4030ed2d3a4491cb0f6142975a15b653be6079b6a4eTadashi G. Takaoka
404b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani    /**
40506bc1db017b14614353137fde035d2eed666a74fTadashi G. Takaoka     * Updates state machine to figure out when to automatically switch back to the previous mode.
406b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani     */
407e38043849e01adfb2f6eb33cf6133c1d39d2466aJean Chalard    public void onEvent(final Event event, final int currentAutoCapsState,
408f091c491ea8259ea696186ea6d97e6ce0c4c3597Jean Chalard            final int currentRecapitalizeState) {
409e38043849e01adfb2f6eb33cf6133c1d39d2466aJean Chalard        mState.onEvent(event, currentAutoCapsState, currentRecapitalizeState);
410923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
411979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
4121fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic    public boolean isShowingKeyboardId(@Nonnull int... keyboardIds) {
4131fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        if (mKeyboardView == null || !mKeyboardView.isShown()) {
4141fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            return false;
4151fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        }
4161fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        int activeKeyboardId = mKeyboardView.getKeyboard().mId.mElementId;
4171fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        for (int keyboardId : keyboardIds) {
4181fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            if (activeKeyboardId == keyboardId) {
4191fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic                return true;
4201fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic            }
4211fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        }
4221fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic        return false;
4231fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic    }
4241fdb8f31562eeef78167585a878eb0450310036bDan Zivkovic
4256fc15b9fc43c791e1fc96e1d5e812ed2e14995eaJean Chalard    public boolean isShowingEmojiPalettes() {
4266fc15b9fc43c791e1fc96e1d5e812ed2e14995eaJean Chalard        return mEmojiPalettesView != null && mEmojiPalettesView.isShown();
427898dbe3c29dc46707897f41dd37845ecaf310b92Satoshi Kataoka    }
428898dbe3c29dc46707897f41dd37845ecaf310b92Satoshi Kataoka
42956e1b7e4f112a268371c84606e6f4239aef91333Ken Wakasa    public boolean isShowingMoreKeysPanel() {
4306fc15b9fc43c791e1fc96e1d5e812ed2e14995eaJean Chalard        if (isShowingEmojiPalettes()) {
43156e1b7e4f112a268371c84606e6f4239aef91333Ken Wakasa            return false;
43256e1b7e4f112a268371c84606e6f4239aef91333Ken Wakasa        }
43356e1b7e4f112a268371c84606e6f4239aef91333Ken Wakasa        return mKeyboardView.isShowingMoreKeysPanel();
43456e1b7e4f112a268371c84606e6f4239aef91333Ken Wakasa    }
43556e1b7e4f112a268371c84606e6f4239aef91333Ken Wakasa
43656e1b7e4f112a268371c84606e6f4239aef91333Ken Wakasa    public View getVisibleKeyboardView() {
4376fc15b9fc43c791e1fc96e1d5e812ed2e14995eaJean Chalard        if (isShowingEmojiPalettes()) {
438d76b55297940a65bb9479020a9ed58aa978a0aeaSatoshi Kataoka            return mEmojiPalettesView;
43956e1b7e4f112a268371c84606e6f4239aef91333Ken Wakasa        }
44056e1b7e4f112a268371c84606e6f4239aef91333Ken Wakasa        return mKeyboardView;
44156e1b7e4f112a268371c84606e6f4239aef91333Ken Wakasa    }
44256e1b7e4f112a268371c84606e6f4239aef91333Ken Wakasa
44327e48447a449d2eb534dfa2dc07060727e1a8fb0Tadashi G. Takaoka    public MainKeyboardView getMainKeyboardView() {
444c150acc7c85ff2f5eeb5bd2c6ff288df4e46a355Tadashi G. Takaoka        return mKeyboardView;
445979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    }
446979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
4470e01df9baf3d9e2fc7b9a51b683ce6df6ff547ddSatoshi Kataoka    public void deallocateMemory() {
4480e01df9baf3d9e2fc7b9a51b683ce6df6ff547ddSatoshi Kataoka        if (mKeyboardView != null) {
4490e01df9baf3d9e2fc7b9a51b683ce6df6ff547ddSatoshi Kataoka            mKeyboardView.cancelAllOngoingEvents();
4500e01df9baf3d9e2fc7b9a51b683ce6df6ff547ddSatoshi Kataoka            mKeyboardView.deallocateMemory();
4510e01df9baf3d9e2fc7b9a51b683ce6df6ff547ddSatoshi Kataoka        }
4520e01df9baf3d9e2fc7b9a51b683ce6df6ff547ddSatoshi Kataoka        if (mEmojiPalettesView != null) {
4530e01df9baf3d9e2fc7b9a51b683ce6df6ff547ddSatoshi Kataoka            mEmojiPalettesView.stopEmojiPalettes();
4540e01df9baf3d9e2fc7b9a51b683ce6df6ff547ddSatoshi Kataoka        }
4550e01df9baf3d9e2fc7b9a51b683ce6df6ff547ddSatoshi Kataoka    }
4560e01df9baf3d9e2fc7b9a51b683ce6df6ff547ddSatoshi Kataoka
457f90fc105ab1159f43f536bcacdd1224c2c05bacbTadashi G. Takaoka    public View onCreateInputView(final boolean isHardwareAcceleratedDrawingEnabled) {
458f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka        if (mKeyboardView != null) {
459f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka            mKeyboardView.closing();
460f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka        }
461f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka
46259c3ef1ff8df23e3c3e3f549c0289c479553c666Tadashi G. Takaoka        updateKeyboardThemeAndContextThemeWrapper(
463311f12d0248f780f901bd76b6cb4e8f8960ce963Tadashi G. Takaoka                mLatinIME, KeyboardTheme.getKeyboardTheme(mLatinIME /* context */));
4641f05cf6dab45c21d1ed334247929434d97c40584Tadashi G. Takaoka        mCurrentInputView = (InputView)LayoutInflater.from(mThemeContext).inflate(
4651f05cf6dab45c21d1ed334247929434d97c40584Tadashi G. Takaoka                R.layout.input_view, null);
4665169937dd48d69e52e647662cb6fc3def5bf90d4Satoshi Kataoka        mMainKeyboardFrame = mCurrentInputView.findViewById(R.id.main_keyboard_frame);
467d76b55297940a65bb9479020a9ed58aa978a0aeaSatoshi Kataoka        mEmojiPalettesView = (EmojiPalettesView)mCurrentInputView.findViewById(
46837beaf1529a61228d6240736937789e5622b29edTadashi G. Takaoka                R.id.emoji_palettes_view);
469f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka
470c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka        mKeyboardView = (MainKeyboardView) mCurrentInputView.findViewById(R.id.keyboard_view);
47152876bbefd774e8647910f73a2e4c17ac4e6bf5cKen Wakasa        mKeyboardView.setHardwareAcceleratedDrawingEnabled(isHardwareAcceleratedDrawingEnabled);
47216950d65c323f99507d97cb7f0403dc653e2506cTadashi G. Takaoka        mKeyboardView.setKeyboardActionListener(mLatinIME);
473d76b55297940a65bb9479020a9ed58aa978a0aeaSatoshi Kataoka        mEmojiPalettesView.setHardwareAcceleratedDrawingEnabled(
4745169937dd48d69e52e647662cb6fc3def5bf90d4Satoshi Kataoka                isHardwareAcceleratedDrawingEnabled);
475d76b55297940a65bb9479020a9ed58aa978a0aeaSatoshi Kataoka        mEmojiPalettesView.setKeyboardActionListener(mLatinIME);
476f3cd2bb33d1688fd6de01787140a1ef2de4b7723Tadashi G. Takaoka        return mCurrentInputView;
4778d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka    }
4788d7ecc70a6572c288064e41235e4ae8ad5b1b47eTadashi G. Takaoka
4796686e63f2158eff07e39ff002ba211d0578f2a4fJean Chalard    public int getKeyboardShiftMode() {
480d445b56ce14152b30143302899790af255691148Tadashi G. Takaoka        final Keyboard keyboard = getKeyboard();
481d445b56ce14152b30143302899790af255691148Tadashi G. Takaoka        if (keyboard == null) {
482d445b56ce14152b30143302899790af255691148Tadashi G. Takaoka            return WordComposer.CAPS_MODE_OFF;
483d445b56ce14152b30143302899790af255691148Tadashi G. Takaoka        }
484d445b56ce14152b30143302899790af255691148Tadashi G. Takaoka        switch (keyboard.mId.mElementId) {
485adbd9ae105e06287b59379d7f7127d95fd0663f4Jean Chalard        case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED:
486adbd9ae105e06287b59379d7f7127d95fd0663f4Jean Chalard        case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED:
487adbd9ae105e06287b59379d7f7127d95fd0663f4Jean Chalard            return WordComposer.CAPS_MODE_MANUAL_SHIFT_LOCKED;
488adbd9ae105e06287b59379d7f7127d95fd0663f4Jean Chalard        case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED:
489adbd9ae105e06287b59379d7f7127d95fd0663f4Jean Chalard            return WordComposer.CAPS_MODE_MANUAL_SHIFTED;
4906686e63f2158eff07e39ff002ba211d0578f2a4fJean Chalard        case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED:
4916686e63f2158eff07e39ff002ba211d0578f2a4fJean Chalard            return WordComposer.CAPS_MODE_AUTO_SHIFTED;
492adbd9ae105e06287b59379d7f7127d95fd0663f4Jean Chalard        default:
493adbd9ae105e06287b59379d7f7127d95fd0663f4Jean Chalard            return WordComposer.CAPS_MODE_OFF;
494adbd9ae105e06287b59379d7f7127d95fd0663f4Jean Chalard        }
495adbd9ae105e06287b59379d7f7127d95fd0663f4Jean Chalard    }
49635c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard
49735c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard    public int getCurrentKeyboardScriptId() {
4985f6c303f0ba70c0bcfd73d06b63f0175669dafc1Jean Chalard        if (null == mKeyboardLayoutSet) {
4995f6c303f0ba70c0bcfd73d06b63f0175669dafc1Jean Chalard            return ScriptUtils.SCRIPT_UNKNOWN;
5005f6c303f0ba70c0bcfd73d06b63f0175669dafc1Jean Chalard        }
50135c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard        return mKeyboardLayoutSet.getScriptId();
50235c37dbef8a65cc1e199a60090d1b4e60da69fe6Jean Chalard    }
503923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project}
504