KeyboardSwitcher.java revision 31adfa78e2edae188edb05e869f9f68798857582
1923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project/*
2443c360d0afdbab091994244f045f4756feaf2b4Jean-Baptiste Queru * Copyright (C) 2008 The Android Open Source Project
3923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project *
4923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * use this file except in compliance with the License. You may obtain a copy of
6923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * the License at
7923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project *
8923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0
9923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project *
10923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * License for the specific language governing permissions and limitations under
14923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project * the License.
15923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project */
16923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
17923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Projectpackage com.android.inputmethod.latin;
18923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
19353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballingerimport java.util.HashMap;
2036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport java.util.Locale;
21353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballingerimport java.util.Map;
22923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
2336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.content.Context;
24979f8690967ff5409fe18f5085858ccdb8e0ccf1satokimport android.content.SharedPreferences;
2536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.content.res.Configuration;
2636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasaniimport android.content.res.Resources;
27979f8690967ff5409fe18f5085858ccdb8e0ccf1satokimport android.preference.PreferenceManager;
28979f8690967ff5409fe18f5085858ccdb8e0ccf1satokimport android.view.InflateException;
2936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
30979f8690967ff5409fe18f5085858ccdb8e0ccf1satokpublic class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceChangeListener {
31923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
32979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    public static final int MODE_NONE = 0;
33923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public static final int MODE_TEXT = 1;
34923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public static final int MODE_SYMBOLS = 2;
35923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public static final int MODE_PHONE = 3;
36923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public static final int MODE_URL = 4;
37923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public static final int MODE_EMAIL = 5;
38923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public static final int MODE_IM = 6;
39cf02653097893b06f24551b790b0f7ec288e704dAmith Yamasani    public static final int MODE_WEB = 7;
40673aed42c3b291fc9f81ead58ca35a5d150f4dcesatok
41923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public static final int KEYBOARDMODE_NORMAL = R.id.mode_normal;
42923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public static final int KEYBOARDMODE_URL = R.id.mode_url;
43923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public static final int KEYBOARDMODE_EMAIL = R.id.mode_email;
44923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    public static final int KEYBOARDMODE_IM = R.id.mode_im;
45cf02653097893b06f24551b790b0f7ec288e704dAmith Yamasani    public static final int KEYBOARDMODE_WEB = R.id.mode_webentry;
46923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
4731adfa78e2edae188edb05e869f9f68798857582satok    public static final String DEFAULT_LAYOUT_ID = "4";
48979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    public static final String PREF_KEYBOARD_LAYOUT = "keyboard_layout";
49979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private static final int[] THEMES = new int [] {
50979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        R.layout.input_basic, R.layout.input_basic_highcontrast, R.layout.input_stone_normal,
5131adfa78e2edae188edb05e869f9f68798857582satok        R.layout.input_stone_bold, R.layout.input_gingerbread};
52979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
53979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    // Ids for each characters' color in the keyboard
54979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private static final int CHAR_THEME_COLOR_WHITE = 0;
55979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private static final int CHAR_THEME_COLOR_BLACK = 1;
56979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
57979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    // Tables which contains resource ids for each character theme color
58979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private static final int[] KBD_PHONE = new int[] {R.xml.kbd_phone, R.xml.kbd_phone_black};
59979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private static final int[] KBD_PHONE_SYMBOLS = new int[] {
60979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        R.xml.kbd_phone_symbols, R.xml.kbd_phone_symbols_black};
61979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private static final int[] KBD_SYMBOLS = new int[] {
62979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        R.xml.kbd_symbols, R.xml.kbd_symbols_black};
63979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private static final int[] KBD_SYMBOLS_SHIFT = new int[] {
64979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        R.xml.kbd_symbols_shift, R.xml.kbd_symbols_shift_black};
65979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private static final int[] KBD_QWERTY = new int[] {R.xml.kbd_qwerty, R.xml.kbd_qwerty_black};
66979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
67b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani    private static final int SYMBOLS_MODE_STATE_NONE = 0;
68b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani    private static final int SYMBOLS_MODE_STATE_BEGIN = 1;
69b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani    private static final int SYMBOLS_MODE_STATE_SYMBOL = 2;
70b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani
71923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    LatinKeyboardView mInputView;
72466741d8a78965b8509bf527344f289e50873092Mike LeBeau    private static final int[] ALPHABET_MODES = {
73466741d8a78965b8509bf527344f289e50873092Mike LeBeau        KEYBOARDMODE_NORMAL,
74466741d8a78965b8509bf527344f289e50873092Mike LeBeau        KEYBOARDMODE_URL,
75466741d8a78965b8509bf527344f289e50873092Mike LeBeau        KEYBOARDMODE_EMAIL,
76cf02653097893b06f24551b790b0f7ec288e704dAmith Yamasani        KEYBOARDMODE_IM,
77cf02653097893b06f24551b790b0f7ec288e704dAmith Yamasani        KEYBOARDMODE_WEB};
78466741d8a78965b8509bf527344f289e50873092Mike LeBeau
7936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    Context mContext;
80979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    LatinIME mInputMethodService;
8131adfa78e2edae188edb05e869f9f68798857582satok
82353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger    private KeyboardId mSymbolsId;
83353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger    private KeyboardId mSymbolsShiftedId;
84353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger
85353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger    private KeyboardId mCurrentId;
86353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger    private Map<KeyboardId, LatinKeyboard> mKeyboards;
87466741d8a78965b8509bf527344f289e50873092Mike LeBeau
88979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private int mMode = MODE_NONE; /** One of the MODE_XXX values */
89923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private int mImeOptions;
90353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger    private boolean mIsSymbols;
91466741d8a78965b8509bf527344f289e50873092Mike LeBeau    private boolean mHasVoice;
92b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani    private boolean mVoiceOnPrimary;
93e3803800c53cc813e27dd1e7c31bdb4d075f0252Amith Yamasani    private boolean mPreferSymbols;
94b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani    private int mSymbolsModeState = SYMBOLS_MODE_STATE_NONE;
95923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
96923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    private int mLastDisplayWidth;
973f7d75060afb2bb7e74879bcbbdcb9700ec5c2d6Amith Yamasani    private LanguageSwitcher mLanguageSwitcher;
9836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    private Locale mInputLocale;
99923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
100979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private int mLayoutId;
101979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
102979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    KeyboardSwitcher(Context context, LatinIME ims) {
103923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mContext = context;
104979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
105979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ims);
106979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        mLayoutId = Integer.valueOf(prefs.getString(PREF_KEYBOARD_LAYOUT, DEFAULT_LAYOUT_ID));
107979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        prefs.registerOnSharedPreferenceChangeListener(this);
108979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
109353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        mKeyboards = new HashMap<KeyboardId, LatinKeyboard>();
110979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        mSymbolsId = makeSymbolsId(false);
111979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        mSymbolsShiftedId = makeSymbolsShiftedId(false);
11236fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        mInputMethodService = ims;
11336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    }
11436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
11536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani    /**
11636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani     * Sets the input locale, when there are multiple locales for input.
11736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani     * If no locale switching is required, then the locale should be set to null.
11836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani     * @param locale the current input locale, or null for default locale with no locale
11936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani     * button.
12036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani     */
1213f7d75060afb2bb7e74879bcbbdcb9700ec5c2d6Amith Yamasani    void setLanguageSwitcher(LanguageSwitcher languageSwitcher) {
1223f7d75060afb2bb7e74879bcbbdcb9700ec5c2d6Amith Yamasani        mLanguageSwitcher = languageSwitcher;
1233f7d75060afb2bb7e74879bcbbdcb9700ec5c2d6Amith Yamasani        mInputLocale = mLanguageSwitcher.getInputLocale();
124923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
125923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
126923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    void setInputView(LatinKeyboardView inputView) {
127923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mInputView = inputView;
128923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
129979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
130979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private KeyboardId makeSymbolsId(boolean hasVoice) {
131979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        return new KeyboardId(KBD_SYMBOLS[getCharColorId()], hasVoice);
132979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    }
133979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
134979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private KeyboardId makeSymbolsShiftedId(boolean hasVoice) {
135979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        return new KeyboardId(KBD_SYMBOLS_SHIFT[getCharColorId()], hasVoice);
136979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    }
137979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
13812e582c79c4e8028bb03971377633440aa95cefbAmith Yamasani    void makeKeyboards(boolean forceCreate) {
139979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        mSymbolsId = makeSymbolsId(mHasVoice && !mVoiceOnPrimary);
140979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        mSymbolsShiftedId = makeSymbolsShiftedId(mHasVoice && !mVoiceOnPrimary);
141979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
14212e582c79c4e8028bb03971377633440aa95cefbAmith Yamasani        if (forceCreate) mKeyboards.clear();
143923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        // Configuration change is coming after the keyboard gets recreated. So don't rely on that.
144923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        // If keyboards have already been made, check if we have a screen width change and
145923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        // create the keyboard layouts again at the correct orientation
14636fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani        int displayWidth = mInputMethodService.getMaxWidth();
147353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        if (displayWidth == mLastDisplayWidth) return;
148353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        mLastDisplayWidth = displayWidth;
14912e582c79c4e8028bb03971377633440aa95cefbAmith Yamasani        if (!forceCreate) mKeyboards.clear();
150353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger    }
151353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger
152353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger    /**
153353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger     * Represents the parameters necessary to construct a new LatinKeyboard,
154353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger     * which also serve as a unique identifier for each keyboard type.
155353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger     */
156353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger    private static class KeyboardId {
157353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        public int mXml;
158466741d8a78965b8509bf527344f289e50873092Mike LeBeau        public int mKeyboardMode; /** A KEYBOARDMODE_XXX value */
159353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        public boolean mEnableShiftLock;
160b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani        public boolean mHasVoice;
161353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger
162b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani        public KeyboardId(int xml, int mode, boolean enableShiftLock, boolean hasVoice) {
163353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            this.mXml = xml;
164466741d8a78965b8509bf527344f289e50873092Mike LeBeau            this.mKeyboardMode = mode;
165353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            this.mEnableShiftLock = enableShiftLock;
166b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani            this.mHasVoice = hasVoice;
167353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        }
168353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger
169b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani        public KeyboardId(int xml, boolean hasVoice) {
170b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani            this(xml, 0, false, hasVoice);
171353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        }
172353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger
173979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        @Override
174353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        public boolean equals(Object other) {
175353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            return other instanceof KeyboardId && equals((KeyboardId) other);
176353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        }
177353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger
178353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        public boolean equals(KeyboardId other) {
179466741d8a78965b8509bf527344f289e50873092Mike LeBeau          return other.mXml == this.mXml
180466741d8a78965b8509bf527344f289e50873092Mike LeBeau              && other.mKeyboardMode == this.mKeyboardMode
18112caec4dd59270787a5ddafdbf39290bc90929b3Amith Yamasani              && other.mEnableShiftLock == this.mEnableShiftLock;
182353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        }
183353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger
184979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        @Override
185353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        public int hashCode() {
186b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani            return (mXml + 1) * (mKeyboardMode + 1) * (mEnableShiftLock ? 2 : 1)
187b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani                    * (mHasVoice ? 4 : 8);
188923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
189923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
190923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
191b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani    void setVoiceMode(boolean enableVoice, boolean voiceOnPrimary) {
192b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani        if (enableVoice != mHasVoice || voiceOnPrimary != mVoiceOnPrimary) {
193b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani            mKeyboards.clear();
194b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani        }
195b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani        mHasVoice = enableVoice;
196b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani        mVoiceOnPrimary = voiceOnPrimary;
197b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani        setKeyboardMode(mMode, mImeOptions, mHasVoice,
198b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani                mIsSymbols);
199b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani    }
200b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani
201b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani    boolean hasVoiceButton(boolean isSymbols) {
202b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani        return mHasVoice && (isSymbols != mVoiceOnPrimary);
203466741d8a78965b8509bf527344f289e50873092Mike LeBeau    }
204466741d8a78965b8509bf527344f289e50873092Mike LeBeau
205466741d8a78965b8509bf527344f289e50873092Mike LeBeau    void setKeyboardMode(int mode, int imeOptions, boolean enableVoice) {
206e3803800c53cc813e27dd1e7c31bdb4d075f0252Amith Yamasani        mSymbolsModeState = SYMBOLS_MODE_STATE_NONE;
207e3803800c53cc813e27dd1e7c31bdb4d075f0252Amith Yamasani        mPreferSymbols = mode == MODE_SYMBOLS;
208979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        if (mode == MODE_SYMBOLS) {
209979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            mode = MODE_TEXT;
210979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        }
211979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        try {
212979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            setKeyboardMode(mode, imeOptions, enableVoice, mPreferSymbols);
213979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        } catch (RuntimeException e) {
214979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            LatinImeLogger.logOnException(mode + "," + imeOptions + "," + mPreferSymbols, e);
215979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        }
216353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger    }
217353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger
2181ca22671191f5079a104bd7c73078561a5f48ef6Amith Yamasani    void setKeyboardMode(int mode, int imeOptions, boolean enableVoice, boolean isSymbols) {
2196516d0fdfcbaa4eb809a8a69bd876293043a68a4Amith Yamasani        if (mInputView == null) return;
220923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mMode = mode;
221923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        mImeOptions = imeOptions;
2221ca22671191f5079a104bd7c73078561a5f48ef6Amith Yamasani        if (enableVoice != mHasVoice) {
2231ca22671191f5079a104bd7c73078561a5f48ef6Amith Yamasani            setVoiceMode(mHasVoice, mVoiceOnPrimary);
2241ca22671191f5079a104bd7c73078561a5f48ef6Amith Yamasani        }
225c5bb4591b67b165f007e29bd9424d319ac3c7c28Brandon Ballinger        mIsSymbols = isSymbols;
226466741d8a78965b8509bf527344f289e50873092Mike LeBeau
227979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        mInputView.setPreviewEnabled(mInputMethodService.getPopupOn());
228353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        KeyboardId id = getKeyboardId(mode, imeOptions, isSymbols);
229979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        LatinKeyboard keyboard = null;
230979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        keyboard = getKeyboard(id);
231353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger
232353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        if (mode == MODE_PHONE) {
233353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            mInputView.setPhoneKeyboard(keyboard);
234353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            mInputView.setPreviewEnabled(false);
235353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        }
236353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger
237353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        mCurrentId = id;
238353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        mInputView.setKeyboard(keyboard);
239353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        keyboard.setShifted(false);
240353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        keyboard.setShiftLocked(keyboard.isShiftLocked());
241353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        keyboard.setImeOptions(mContext.getResources(), mMode, imeOptions);
242979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        keyboard.setBlackFlag(isBlackSym());
243353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger    }
244353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger
245353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger    private LatinKeyboard getKeyboard(KeyboardId id) {
246353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        if (!mKeyboards.containsKey(id)) {
24736fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            Resources orig = mContext.getResources();
24836fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            Configuration conf = orig.getConfiguration();
24936fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            Locale saveLocale = conf.locale;
25036fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            conf.locale = mInputLocale;
25136fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            orig.updateConfiguration(conf, null);
252353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            LatinKeyboard keyboard = new LatinKeyboard(
2531ca22671191f5079a104bd7c73078561a5f48ef6Amith Yamasani                mContext, id.mXml, id.mKeyboardMode);
254979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            keyboard.setVoiceMode(hasVoiceButton(id.mXml == R.xml.kbd_symbols
255979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                    || id.mXml == R.xml.kbd_symbols_black), mHasVoice);
2563f7d75060afb2bb7e74879bcbbdcb9700ec5c2d6Amith Yamasani            keyboard.setLanguageSwitcher(mLanguageSwitcher);
257979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            keyboard.setBlackFlag(isBlackSym());
258358e485b14938fbcb5af5be75aa29f2b73674100Amith Yamasani
259353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            if (id.mEnableShiftLock) {
260353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger                keyboard.enableShiftLock();
261353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            }
262353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            mKeyboards.put(id, keyboard);
26336fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani
26436fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            conf.locale = saveLocale;
26536fcf25833f7c8876cbc8286e0c159b052dc2626Amith Yamasani            orig.updateConfiguration(conf, null);
266353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        }
267353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        return mKeyboards.get(id);
268353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger    }
269353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger
270353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger    private KeyboardId getKeyboardId(int mode, int imeOptions, boolean isSymbols) {
271b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani        boolean hasVoice = hasVoiceButton(isSymbols);
272979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        int charColorId = getCharColorId();
273979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        // TODO: generalize for any KeyboardId
274979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        int keyboardRowsResId = KBD_QWERTY[charColorId];
275353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        if (isSymbols) {
276979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            if (mode == MODE_PHONE) {
277979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                return new KeyboardId(KBD_PHONE_SYMBOLS[charColorId], hasVoice);
278979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            } else {
279979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                return new KeyboardId(KBD_SYMBOLS[charColorId], hasVoice);
280979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            }
281353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        }
282923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        switch (mode) {
283979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            case MODE_NONE:
284979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                LatinImeLogger.logOnWarning(
285979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                        "getKeyboardId:" + mode + "," + imeOptions + "," + isSymbols);
286979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                /* fall through */
287923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            case MODE_TEXT:
288979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                return new KeyboardId(keyboardRowsResId, KEYBOARDMODE_NORMAL, true, hasVoice);
289923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            case MODE_SYMBOLS:
290979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                return new KeyboardId(KBD_SYMBOLS[charColorId], hasVoice);
291923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            case MODE_PHONE:
292979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                return new KeyboardId(KBD_PHONE[charColorId], hasVoice);
293923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            case MODE_URL:
294979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                return new KeyboardId(keyboardRowsResId, KEYBOARDMODE_URL, true, hasVoice);
295923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            case MODE_EMAIL:
296979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                return new KeyboardId(keyboardRowsResId, KEYBOARDMODE_EMAIL, true, hasVoice);
297923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project            case MODE_IM:
298979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                return new KeyboardId(keyboardRowsResId, KEYBOARDMODE_IM, true, hasVoice);
299cf02653097893b06f24551b790b0f7ec288e704dAmith Yamasani            case MODE_WEB:
300979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                return new KeyboardId(keyboardRowsResId, KEYBOARDMODE_WEB, true, hasVoice);
301923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
302353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        return null;
303923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
304923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
305923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    int getKeyboardMode() {
306923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        return mMode;
307923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
308923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
309923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    boolean isTextMode() {
310923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        return mMode == MODE_TEXT;
311923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
312923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
313923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    boolean isAlphabetMode() {
31417dc363a63a20d18cd8161f917899b39aed6ddd6Ken Wakasa        if (mCurrentId == null) {
31517dc363a63a20d18cd8161f917899b39aed6ddd6Ken Wakasa            return false;
31617dc363a63a20d18cd8161f917899b39aed6ddd6Ken Wakasa        }
317466741d8a78965b8509bf527344f289e50873092Mike LeBeau        int currentMode = mCurrentId.mKeyboardMode;
318466741d8a78965b8509bf527344f289e50873092Mike LeBeau        for (Integer mode : ALPHABET_MODES) {
319b1cd7016028f5770da2688f1ec51e0601fc5b9ebAmith Yamasani            if (currentMode == mode) {
320466741d8a78965b8509bf527344f289e50873092Mike LeBeau                return true;
321466741d8a78965b8509bf527344f289e50873092Mike LeBeau            }
322466741d8a78965b8509bf527344f289e50873092Mike LeBeau        }
323466741d8a78965b8509bf527344f289e50873092Mike LeBeau        return false;
324923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
325923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
326979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    void setShifted(boolean shifted) {
327979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        if (mInputView != null) {
328979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            mInputView.setShifted(shifted);
329979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        }
330979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    }
331979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
332979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    void setShiftLocked(boolean shiftLocked) {
333979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        if (mInputView != null) {
334979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            mInputView.setShiftLocked(shiftLocked);
335979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        }
336979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    }
337979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
338923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    void toggleShift() {
339353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        if (mCurrentId.equals(mSymbolsId)) {
340353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            LatinKeyboard symbolsKeyboard = getKeyboard(mSymbolsId);
341353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            LatinKeyboard symbolsShiftedKeyboard = getKeyboard(mSymbolsShiftedId);
342353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            symbolsKeyboard.setShifted(true);
343353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            mCurrentId = mSymbolsShiftedId;
344353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            mInputView.setKeyboard(symbolsShiftedKeyboard);
345353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            symbolsShiftedKeyboard.setShifted(true);
346353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            symbolsShiftedKeyboard.setImeOptions(mContext.getResources(), mMode, mImeOptions);
347353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger        } else if (mCurrentId.equals(mSymbolsShiftedId)) {
348353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            LatinKeyboard symbolsKeyboard = getKeyboard(mSymbolsId);
349353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            LatinKeyboard symbolsShiftedKeyboard = getKeyboard(mSymbolsShiftedId);
350353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            symbolsShiftedKeyboard.setShifted(false);
351353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            mCurrentId = mSymbolsId;
352979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            mInputView.setKeyboard(symbolsKeyboard);
353353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            symbolsKeyboard.setShifted(false);
354353da6d207bed3d32ec38b9ce52e4a136adbf060Brandon Ballinger            symbolsKeyboard.setImeOptions(mContext.getResources(), mMode, mImeOptions);
355923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project        }
356923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
357923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project
358923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    void toggleSymbols() {
359466741d8a78965b8509bf527344f289e50873092Mike LeBeau        setKeyboardMode(mMode, mImeOptions, mHasVoice, !mIsSymbols);
360e3803800c53cc813e27dd1e7c31bdb4d075f0252Amith Yamasani        if (mIsSymbols && !mPreferSymbols) {
361b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani            mSymbolsModeState = SYMBOLS_MODE_STATE_BEGIN;
362b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani        } else {
363b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani            mSymbolsModeState = SYMBOLS_MODE_STATE_NONE;
364b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani        }
365b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani    }
366b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani
367b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani    /**
368b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani     * Updates state machine to figure out when to automatically switch back to alpha mode.
369b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani     * Returns true if the keyboard needs to switch back
370b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani     */
371b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani    boolean onKey(int key) {
372d67fe0e7583f1be18b35b33b7658e4427f1e3dedAmith Yamasani        // Switch back to alpha mode if user types one or more non-space/enter characters
373d67fe0e7583f1be18b35b33b7658e4427f1e3dedAmith Yamasani        // followed by a space/enter
374b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani        switch (mSymbolsModeState) {
375b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani            case SYMBOLS_MODE_STATE_BEGIN:
376d67fe0e7583f1be18b35b33b7658e4427f1e3dedAmith Yamasani                if (key != LatinIME.KEYCODE_SPACE && key != LatinIME.KEYCODE_ENTER && key > 0) {
377d67fe0e7583f1be18b35b33b7658e4427f1e3dedAmith Yamasani                    mSymbolsModeState = SYMBOLS_MODE_STATE_SYMBOL;
378d67fe0e7583f1be18b35b33b7658e4427f1e3dedAmith Yamasani                }
379b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani                break;
380b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani            case SYMBOLS_MODE_STATE_SYMBOL:
381d67fe0e7583f1be18b35b33b7658e4427f1e3dedAmith Yamasani                if (key == LatinIME.KEYCODE_ENTER || key == LatinIME.KEYCODE_SPACE) return true;
382b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani                break;
383b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani        }
384b19668cfc17ad30afcc3c8c0407d47238ce1a90dAmith Yamasani        return false;
385923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project    }
386979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
387979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    public LatinKeyboardView getInputView() {
388979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        return mInputView;
389979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    }
390979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
391979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    public void recreateInputView() {
392979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        changeLatinKeyboardView(mLayoutId, true);
393979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    }
394979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
395979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private void changeLatinKeyboardView(int newLayout, boolean forceReset) {
396979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        if (mLayoutId != newLayout || mInputView == null || forceReset) {
397979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            if (mInputView != null) {
398979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                mInputView.closing();
399979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            }
400979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            if (THEMES.length <= newLayout) {
401979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                newLayout = Integer.valueOf(DEFAULT_LAYOUT_ID);
402979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            }
403979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
404979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            LatinIMEUtil.GCUtils.getInstance().reset();
405979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            boolean tryGC = true;
406979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            for (int i = 0; i < LatinIMEUtil.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
407979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                try {
408979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                    mInputView = (LatinKeyboardView) mInputMethodService.getLayoutInflater(
409979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                            ).inflate(THEMES[newLayout], null);
410979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                    tryGC = false;
411979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                } catch (OutOfMemoryError e) {
412979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                    tryGC = LatinIMEUtil.GCUtils.getInstance().tryGCOrWait(
413979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                            mLayoutId + "," + newLayout, e);
414979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                } catch (InflateException e) {
415979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                    tryGC = LatinIMEUtil.GCUtils.getInstance().tryGCOrWait(
416979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                            mLayoutId + "," + newLayout, e);
417979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                }
418979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            }
419979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            mInputView.setOnKeyboardActionListener(mInputMethodService);
420979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            mLayoutId = newLayout;
421979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        }
422979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        mInputMethodService.mHandler.post(new Runnable() {
423979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            public void run() {
424979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                if (mInputView != null) {
425979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                    mInputMethodService.setInputView(mInputView);
426979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                }
427979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                mInputMethodService.updateInputViewShown();
428979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            }});
429979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    }
430979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
431979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
432979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        if (PREF_KEYBOARD_LAYOUT.equals(key)) {
433979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            changeLatinKeyboardView(
434979f8690967ff5409fe18f5085858ccdb8e0ccf1satok                    Integer.valueOf(sharedPreferences.getString(key, DEFAULT_LAYOUT_ID)), false);
435979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        }
436979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    }
437979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
438979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    public boolean isBlackSym () {
439979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        if (mInputView != null && mInputView.getSymbolColorSheme() == 1) {
440979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            return true;
441979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        }
442979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        return false;
443979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    }
444979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
445979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    private int getCharColorId () {
446979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        if (isBlackSym()) {
447979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            return CHAR_THEME_COLOR_BLACK;
448979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        } else {
449979f8690967ff5409fe18f5085858ccdb8e0ccf1satok            return CHAR_THEME_COLOR_WHITE;
450979f8690967ff5409fe18f5085858ccdb8e0ccf1satok        }
451979f8690967ff5409fe18f5085858ccdb8e0ccf1satok    }
452979f8690967ff5409fe18f5085858ccdb8e0ccf1satok
453923bf41f853a544fd0d71fbf7dc90359ec35981The Android Open Source Project}
454